如何根据字段键的相应值过滤字典键

Hoo*_*ops 58 python dictionary

我有:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17}
Run Code Online (Sandbox Code Playgroud)

我想迭代这个字典,但是在值而不是键上,所以我可以在另一个函数中使用这些值.

例如,我想测试哪些字典值大于6,然后将它们的键存储在列表中.我的代码看起来像这样:

list = []
for c in dictionary:
    if c > 6:
        list.append(dictionary[c])
print list
Run Code Online (Sandbox Code Playgroud)

然后,在一个完美的世界中,list将显示所有值大于的键6.但是,我的for循环只是遍历键; 我想改变它的价值观!

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

jam*_*lak 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']
Run Code Online (Sandbox Code Playgroud)

我想更新这个答案,以便展示@glarrain的解决方案,我发现自己现在倾向于使用它.

[k for k in d if d[k] > 6]
Run Code Online (Sandbox Code Playgroud)

这是完全交叉兼容的,并且不需要从.iteritems(.iteritems避免将列表保存到Python 3中的内存,在Python 3中修复)到令人困惑的更改.items.

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

from six import iteritems
Run Code Online (Sandbox Code Playgroud)

这有效地修复了交叉兼容性问题但是要求您下载包 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
Run Code Online (Sandbox Code Playgroud)

然而,这些只是小字典的测试,在巨大的字典中,我很确定没有字典键查找(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
Run Code Online (Sandbox Code Playgroud)

  • 对于python 2.x,`d.iteritems()`会更好AFAIK. (5认同)

Sio*_*e21 36

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

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


Vik*_*kas 10

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

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