如何根据其对应的值过滤字典键

我有:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 

我想遍历这个字典,但通过值而不是键,所以我可以使用另一个函数中的值。

例如,我想testing哪些字典值大于6 ,然后将它们的密钥存储在列表中。 我的代码如下所示:

 list = [] for c in dictionary: if c > 6: list.append(dictionary[c]) print list 

然后,在一个完美的世界里, list将包含所有的值大于6的键。 但是,我for循环只是迭代的关键; 我想改变这个价值!

任何帮助是极大的赞赏。 谢谢

 >>> d = {"foo": 12, "bar": 2, "jim": 4, "bob": 17} >>> [k for k, v in d.items() if v > 6] # Use d.iteritems() on python 2.x ['bob', 'foo'] 

我想只是更新这个答案,也展示了我现在倾向于使用的@ glarrain的解决scheme。

 [k for k in d if d[k] > 6] 

这是完全交叉兼容的,不需要从.iteritems.iteritems避免将Python 2上的内存保存到Python 3上的内存)到.items

法肯教授提到了解决这个问题的方法

 from six import iteritems 

这有效地解决了交叉兼容性问题,但是需要你下载软件包six

然而,我不完全赞同@glarrain这个解决scheme更具可读性,这是争论,也许只是一个个人的喜好,即使Python应该只有一种方法来做到这一点。 在我看来,这取决于情况(例如,你可能有一个很长的字典名称,你不希望键入两次,或者你想给这些值更可读的名称或其他原因)

一些有趣的时机:

在Python 2中,第二种解决scheme速度更快,在Python 3中,它们在原始速度上几乎完全相同。


 $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 1000000 loops, best of 3: 0.772 usec per loop $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.iteritems() if v > 6]' 1000000 loops, best of 3: 0.508 usec per loop $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 1000000 loops, best of 3: 0.45 usec per loop $ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 1000000 loops, best of 3: 1.02 usec per loop $ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 1000000 loops, best of 3: 1.02 usec per loop 

但是,这些只是小字典的testing,在很大的字典中,我敢肯定没有字典键查找( d[k] )会使得.items更快。 而这似乎是这样的

 $ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 1 loops, best of 3: 1.75 sec per loop $ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.iteritems() if v > 6]' 1 loops, best of 3: 1.71 sec per loop $ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 1 loops, best of 3: 3.08 sec per loop $ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.items() if v > 6]' 1 loops, best of 3: 2.47 sec per loop 

要获取值,请使用dictionary.values()

要获取键值对,可以使用dictionary.items()

在字典上使用itemsiteritems 。 就像是:

 list = [] for k, v in dictionary.iteritems(): if v > 6: list.append(k) print list 

这个怎么样:

 dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} for val in dictionary.values(): # do something 

这取决于你是否想修改字典(添加或删除项目)或不。 如果没有,那么你可以尝试:

 for value in dictionary.itervalues(): #this returns a generator print "do something with the value" 

另外,如果你修改字典,你应该迭代一个值的副本:

 for value in dictionary.values(): #this returns a list of values print "do something with the value" 

如果你想同时使用键和值,你可以使用dictionary.iteritems()dictionary.items()

我认为最好的方法是考虑迁移到Python 3

 >>> mydict = {'foo': 12, 'bar': 2, 'jim': 4, 'bob': 17} >>> [k for k in mydict if mydict[k] > 6] ['bob', 'foo'] 

“最好”的标准是可读性。

(免责声明:我的答案是根据Alex Martelli对其他问题的回答https://stackoverflow.com/a/3744713/556413和@ jamylak的这个问题)