我有一个要排序的元组列表。元组包含字符串:

connectionsList = [('C', 'B'), ('A', 'C'), ('D', 'B'), ('C','D')]


元组中的字符串具有存储在dict中的数字值:

valuesDict = {'A':3, 'B':5, 'C':1, 'D':2}


我想做的是按照元组dict中的值总和对列表进行排序。此玩具示例的所需输出为:

[(C,D), (A,C), (C,B), (D,B)]


其总和为:

[3, 4, 6, 7]


使用itemgetter,我可以按位置按字母顺序排序:

sortedView = sorted(connectionsList, key=itemgetter(0,1))


但是,我在字典中查找itemgetter的值时遇到了麻烦。运行此:

sortedView = sorted(connectionsList, key=valuesDict[itemgetter(0)] + valuesDict[itemgetter(1)])


给出dict错误KeyError:operator.itemgetter(0)。

如何根据字典中的值创建排序?

最佳答案

不要使用itemgetter实例;您需要给他们打电话,但他们在这里过大了。

只需将传递给keylambda值直接访问字典。这是一个元组,因此添加索引:

sortedView = sorted(connectionsList, key=lambda k: valuesDict[k[0]] + valuesDict[k[1]])


key参数必须是一个可调用对象,该对象接受一个参数(正在排序的项之一),并返回您实际在其上进行排序的值。 itemgetter()返回基于您调用对象的索引的结果; itemgetter(0)(some_tuple)将返回传入的元组的第一个元素。

Lambda可以执行相同的操作,在上述解决方案中,Lambda返回给定元组的所需总和。

演示:

>>> connectionsList = [('C', 'B'), ('A', 'C'), ('D', 'B'), ('C','D')]
>>> valuesDict = {'A':3, 'B':5, 'C':1, 'D':2}
>>> sorted(connectionsList, key=lambda k: valuesDict[k[0]] + valuesDict[k[1]])
[('C', 'D'), ('A', 'C'), ('C', 'B'), ('D', 'B')]


您也可以将元组视为任意长度的序列。如果然后还要考虑不是元组中的所有值都不是valuesDict映射的有效键的可能性(取而代之的是0),则还可以通过以下方法获得解决方案:

sortedView = sorted(connectionsList, key=lambda k: sum(valuesDict.get(v, 0) for v in k))


这是更通用和更可靠的。

您也不需要按字母顺序使用itemgetter()对象。元组已经按0, 1顺序提供,因此无需使用排序键就可以得到相同的排序顺序。

10-01 17:39