58

我有:

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

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

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

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

然后,在一个完美的世界中,list将包含所有值大于的键6。但是,我的for循环只是遍历键;我想将其更改为值!

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

4

6 回答 6

82
>>> 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 的解决方案,我发现自己现在倾向于使用它。

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

这是完全交叉兼容的,不需要从.iteritems(.iteritems避免在 Python 2 上将列表保存到内存中,这在 Python 3 中已修复) 到.items.

@Prof.Falken 提到了这个问题的解决方案

from six import iteritems

这有效地解决了交叉兼容性问题但需要您下载包six

但是,我不完全同意@glarrain 的观点,即这个解决方案更具可读性,这是有争议的,也许只是个人偏好,即使 Python 应该只有一种方法可以做到这一点。在我看来,这取决于情况(例如,您可能有一个很长的字典名称,您不想输入两次,或者您想给这些值一个更易读的名称或其他原因)

一些有趣的时间:

在 Python 2 中,第二种解决方案更快,在 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

然而,这些只是对小型字典的测试,在大型字典中,我很确定没有字典键查找 ( 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
于 2012-05-08T11:59:57.827 回答
36

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

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

于 2012-05-08T12:00:17.187 回答
10

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

list = []
for k, v in dictionary.iteritems():
  if v > 6:
    list.append(k)
print list
于 2012-05-08T12:01:34.873 回答
4

这个怎么样:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17}
for val in dictionary.values():
    # do something
于 2012-05-08T12:00:10.813 回答
4

我认为最好的方法(考虑迁移到 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 对这个问题的回答)

于 2013-05-28T14:42:45.950 回答
2

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

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()

于 2012-05-08T12:03:37.107 回答