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これは完全に相互互換性があり、 (.iteritemsPython3で修正された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
于 2012-05-08T11:59:57.827 に答える
36

値を取得するには、次を使用しますdictionary.values()

キーと値のペアを取得するには、dictionary.items()

于 2012-05-08T12:00:17.187 に答える
10

itemsまたはiteritems辞書で使用します。何かのようなもの:

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 に答える