>>> 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
Python3で修正されたPython2のメモリにリストを保存することを回避する)からへの紛らわしい変更を必要としません.items
。
@ Prof.Falkenは、この問題の解決策について言及しました
from six import iteritems
相互互換性の問題を効果的に修正しますが、パッケージをダウンロードする必要がありますsix
しかし、私は@glarrainに完全には同意しません。このソリューションの方が読みやすく、議論の余地があり、Pythonには1つの方法しかないと想定されているにもかかわらず、個人的な好みかもしれません。私の意見では、状況によって異なります(たとえば、長い辞書名を2回入力したくない場合や、値に読みやすい名前を付けたい場合など)。
いくつかの興味深いタイミング:
Python 2では、2番目のソリューションの方が高速です。Python3では、生の速度はほぼ同じです。
$ 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