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