'for'ループを使用して辞書を反復処理する

2010年07月21日に質問されました。  ·  閲覧回数 4.5M回  ·  ソース

TopChef picture
2010年07月21日

私は次のコードに少し戸惑っています:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

私が理解していないのはkey部分です。 Pythonは、辞書からキーを読み取るだけでよいことをどのように認識しますか? keyはPythonの特別な単語ですか? それとも単に変数ですか?

回答

sberry picture
2010年07月21日
5632

keyは単なる変数名です。

for key in d:

キーと値ではなく、辞書内のキーをループするだけです。 キーと値の両方をループするには、次を使用できます。

Python 3.xの場合:

for key, value in d.items():

Python 2.xの場合:

for key, value in d.iteritems():

自分でテストするには、単語keypoopます。

Python 3.xでは、 iteritems()は単にitems() iteritems()に置き換えられました。これは、 iteritems()ように、dictに裏打ちされたセットのようなビューを返しますが、さらに優れています。 これは、2.7ではviewitems()としても利用できます。

操作items()は2と3の両方で機能しますが、2では、辞書の(key, value)ペアのリストが返されます。これは、 items()後に発生するdictへの変更を反映しません。 list(d.items())呼び出すことができます。

ars picture
2010年07月21日
466

キーが特別な単語であるというわけではありませんが、辞書はイテレータプロトコルを実装しています。 クラスでこれを行うことができます。たとえば、クラスイテレータを構築する方法については、この質問を参照してください。

辞書の場合、経営幹部レベルで実装されます。 詳細はPEP234に記載されています。 特に、「辞書イテレータ」というタイトルのセクション:

  • ディクショナリは、ディクショナリのキーを反復処理する効率的なイテレータを返すtp_iterスロットを実装します。 [...]これは私たちが書くことができることを意味します

    for k in dict: ...
    

    これは同等ですが、はるかに高速です

    for k in dict.keys(): ...
    

    (ループまたは別のスレッドによる)辞書への変更の制限に違反しない限り。

  • さまざまな種類のイテレータを明示的に返すディクショナリにメソッドを追加します。

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    これは、 for x in dictfor x in dict.iterkeys()省略形であることを意味します。

Python 3では、 dict.iterkeys()dict.itervalues() 、およびdict.iteritems()はサポートされなくなりました。 代わりに、 dict.keys()dict.values() 、およびdict.items()使用してください。

John La Rooy picture
2010年07月21日
222

dict反復処理すると、次のように、キーを特定の順序で反復処理します。

編集:(これはPython3.6ませんが、動作がないことに注意してください)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

あなたの例では、 dict.items()を使用することをお勧めします:

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

これにより、タプルのリストが表示されます。 このようにループすると、各タプルは自動的にkv解凍されます。

for k,v in d.items():
    print(k, 'corresponds to', v)

使用してkvオーバーループするとき、変数名としてdictループの本体はわずか数行であれば非常に一般的です。 より複雑なループの場合は、よりわかりやすい名前を使用することをお勧めします。

for letter, number in d.items():
    print(letter, 'corresponds to', number)

フォーマット文字列を使用する習慣を身につけることをお勧めします。

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))
ssoler picture
2010年07月21日
94

keyは単なる変数です。

Python2.Xの場合

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

...またはそれ以上、

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Python3.Xの場合

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)
Alexander Gessler picture
2010年07月21日
67

for .. in .. -syntaxを使用して辞書を反復処理する場合、常にキーを反復処理します(値にはdictionary[key]を使用してアクセスできます)。

キーと値のペアを反復処理するには、Python 2ではfor k,v in s.iteritems()を使用し、Python 3ではfor k,v in s.items()ます。

chryss picture
2010年07月21日
35

これは非常に一般的なループイディオムです。 inは演算子です。 どのような場合に使用するためのfor key in dictとするとき、それがなければなりませんfor key in dict.keys()見るデビッドGoodgerの慣用的なPythonの記事(アーカイブコピー)

Aaron Hall picture
2017年06月21日
23

'for'ループを使用して辞書を反復処理する

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

Pythonは、辞書からキーを読み取るだけでよいことをどのように認識しますか? キーはPythonの特別な単語ですか? それとも単に変数ですか?

forループだけで

辞書は、キーから値へのマッピングです。

d = {'x': 1, 'y': 2, 'z': 3} 

それを繰り返すときはいつでも、キーを繰り返します。 変数名keyは、説明を目的としたものであり、その目的に非常に適しています。

これはリスト内包で起こります:

>>> [k for k in d]
['x', 'y', 'z']

これは、辞書をリスト(またはその他のコレクションタイプのオブジェクト)に渡すときに発生します。

>>> list(d)
['x', 'y', 'z']

Pythonが反復する方法は、必要なコンテキストで、イテレータ(この場合はキーイテレータオブジェクト)を返すオブジェクト(この場合はディクショナリ)の__iter__メソッドを呼び出します。

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

これらの特別なメソッドを自分で使用するのではなく、それぞれの組み込み関数を使用して、 iterを呼び出します。

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

イテレータには__next__メソッドがありますが、組み込み関数nextを使用して呼び出します。

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

イテレータが使い果たされると、 StopIterationます。 これは、Pythonがforループ、リスト内包表記、ジェネレーター式、またはその他の反復コンテキストを終了することを知っている方法です。 イテレータがStopIterationを上げると、常にそれが上がります。もう一度繰り返したい場合は、新しいものが必要です。

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

口述に戻る

多くのコンテキストでdictが繰り返されるのを見てきました。 私たちが見たのは、口述を繰り返すたびに、鍵を取得するということです。 元の例に戻る:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

変数名を変更しても、キーは取得されます。 試してみよう:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

値を反復処理する場合は、 .valuesメソッドのdictを使用するか、両方を一緒に使用する必要があります。 .items

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

与えられた例では、次のような項目を反復処理する方が効率的です。

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

しかし、学術的な目的では、質問の例は問題ありません。

jdhao picture
2017年05月25日
21

キー、値のペア、および現在地を示すインデックスを取得するためにdictを反復処理する必要があるユースケースがあります。 これが私のやり方です:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

キーの周りの括弧、値は重要であることに注意してください。括弧がないと、「解凍するのに十分な値がありません」というValueErrorが発生します。

Ankur Agarwal picture
2017年11月03日
10

GitHubでCPythonのdicttypeの実装を確認できます。 これは、dictイテレータを実装するメソッドのシグネチャです。

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c

Neil Chowdhury  o_O picture
2016年01月01日
5

キーを反復処理するには、速度は遅くなりますが、 my_dict.keys()を使用することをお勧めします。 あなたがこのようなことをしようとした場合:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

プログラムの実行中にキーを変更しているため、ランタイムエラーが発生します。 絶対に時間を短縮することに固執している場合は、 for key in my_dict方法を使用してください。ただし、警告が表示されています;)。