从Dict(python)中的itemgetter查找值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Dict(python)中的itemgetter查找值相关的知识,希望对你有一定的参考价值。
我有一个我正在尝试排序的元组列表。元组包含字符串:
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))
但是,我在查找dict中itemgetter的值时遇到问题。运行这个:
sortedView = sorted(connectionsList, key=valuesDict[itemgetter(0)] + valuesDict[itemgetter(1)])
给出KeyError的dict错误:operator.itemgetter(0)。
如何根据dict中的值创建排序?
不要使用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
顺序提供,因此您可以在不使用排序键的情况下获得相同的排序顺序。
如果你想使用valuesDict
查找sum
和itemgetter
中的键,你必须做这样的事情:
>>> from operator import itemgetter
>>> connectionsList = [('C', 'B'), ('A', 'C'), ('D', 'B'), ('C','D')]
>>> valuesDict = {'A':3, 'B':5, 'C':1, 'D':2}
>>> idx = 0
>>> sum(itemgetter(*itemgetter(0, 1)(connectionsList[idx]))(valuesDict))
6
connectionsList[idx]
是传递给key
函数的当前元素。所以你需要对它进行转换,以便实际的键函数只需要当前元素作为参数:
>>> def keyfunc(cur_element):
... return sum(itemgetter(*itemgetter(0, 1)(cur_element))(valuesDict))
>>> sorted(connectionsList, key=keyfunc)
[('C', 'D'), ('A', 'C'), ('C', 'B'), ('D', 'B')]
然而,与没有itemgetter
的解决方案相比,这不是真的可读:
>>> def keyfun(cur_element):
... i1, i2 = cur_element
... return valuesDict[i1] + valuesDict[i2]
>>> sorted(connectionsList, key=keyfunc)
[('C', 'D'), ('A', 'C'), ('C', 'B'), ('D', 'B')]
所以在这种情况下你可能不应该使用itemgetter
,因为它涉及更多的函数调用,结果函数不是很好。
如果valuesDict
字典中可能缺少某些键,则应使用[]
调用替换get
loopup:
>>> def keyfun(cur_element):
... i1, i2 = cur_element
... return valuesDict.get(i1, 0) + valuesDict.get(i2, 0)
>>> sorted(connectionsList, key=keyfunc)
[('C', 'D'), ('A', 'C'), ('C', 'B'), ('D', 'B')]
注意当qzzxswpois变得更复杂时,我通常更喜欢正常的def
函数,但这是一个品味问题。在这种情况下,很容易将它们翻译成lambda
s。
你可以尝试这样的事情:
首先收集列表中的sum和tuple:
lambda
它会给:
connectionsList = [('C', 'B'), ('A', 'C'), ('D', 'B'), ('C','D')]
valuesDict = {'A':3, 'B':5, 'C':1, 'D':2}
tuple_sum=[]
for i in connectionsList:
tuple_sum.append((valuesDict.get(i[0])+valuesDict.get(i[1]),i))
现在对它进行排序并仅采用嵌套元组:
[(6, ('C', 'B')), (4, ('A', 'C')), (7, ('D', 'B')), (3, ('C', 'D'))]
输出:
print(list(map(lambda x:x[1],sorted(tuple_sum))))
以上是关于从Dict(python)中的itemgetter查找值的主要内容,如果未能解决你的问题,请参考以下文章
python学习 -- operator.itemgetter(), list.sort/sorted 以及lambda函数
关于python中的operator.itemgetter()函数的用法