Pythonでディクショナリを反復処理するときに.items()を呼び出す必要があるのはなぜですか?


131

items()ディクショナリのキーと値のペアを反復処理するために呼び出す必要があるのはなぜですか?すなわち。

dic = {'one': '1', 'two': '2'}
for k, v in dic.items():
    print(k, v)

辞書を反復するデフォルトの動作ではないのはなぜですか

for k, v in dic:
    print(k, v)

回答:


171

すべてのpythonコンテナーCの期待は

for item in C:
    assert item in C

うまくいきます- in(ループ節の)1つの意味が他の(存在検査)と完全に異なる意味を持っていたとしたら、それは驚くべきことではないでしょうか?きっと!リスト、セット、タプルなどは自然にそのように機能します...

したがって、C辞書の場合inforループ内でキー/値のタプルを生成する場合、最小の驚きの原則により、inそのようなタプルを包含チェックの左側のオペランドとして取得する必要があります。

それはどの程度役に立ちますか?まったく役に立たない、基本的にif (key, value) in Cは同義語を作成するif C.get(key) == value-これは、if k in C実際に実行したことよりも100倍少ない頻度で実行した、または実行したかったと思うチェックです確認するためのチェックであり、キーの存在のみをチェックし、値を完全に無視します。

一方、キーだけでループすることは非常に一般的です。例:

for k in thedict:
    thedict[k] += 1

同様に値を持つことは特に役に立ちません:

for k, v in thedict.items():
    thedict[k] = v + 1

実際はやや不明確で簡潔ではありません。(これitemsは、キーと値のペアを取得するために使用する「適切な」メソッドの元のスペルであったことに注意してください。残念ながら、そのようなアクセサがリスト全体を返した時代に戻ったため、「ただ繰り返す」ことをサポートするには、代替スペルを導入する必要がありました。 、iteritems それは-以前のバージョンのPythonとの後方互換性の制約が大幅に弱められたPython 3ではitems再びなりました)。


10

私の推測では、完全なタプルを使用する方がループの方が直感的ですが、を使用してメンバーシップをテストする場合はそうではないかもしれませんin

if key in counts:
    counts[key] += 1
else:
    counts[key] = 1

のキーと値の両方を指定する必要がある場合、そのコードは実際には機能しませんin。キーと値の両方が辞書にあるかどうかをチェックするユースケースを想像するのに苦労しています。キーをテストするだけの方がはるかに自然です。

# When would you ever write a condition like this?
if (key, value) in dict:

これで、inオペレーターとfor ... in同じアイテムを操作する必要がなくなりました。実装に関しては、それらは異なる操作です(__contains____iter__)。しかし、そのわずかな不一致は、やや混乱を招き、まあ、一貫性がなくなります。


用することを考えると、すべて、私は考えることができることを反復可能な組み込みの他のタイプのx in foo場合にだけiではfor i in fooの値を前提としx、いくつかの点では、私はそれが非常だろうと言う巨大な矛盾。
aaronasterling 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.