我有一个要排序的元组列表。元组包含字符串:
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
实例;您需要给他们打电话,但他们在这里过大了。
只需将传递给key
的lambda
值直接访问字典。这是一个元组,因此添加索引:
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
顺序提供,因此无需使用排序键就可以得到相同的排序顺序。