回答:
すべてのpythonコンテナーCの期待は
for item in C:
assert item in C
うまくいきます- in
(ループ節の)1つの意味が他の(存在検査)と完全に異なる意味を持っていたとしたら、それは驚くべきことではないでしょうか?きっと!リスト、セット、タプルなどは自然にそのように機能します...
したがって、C
辞書の場合in
、for
ループ内でキー/値のタプルを生成する場合、最小の驚きの原則により、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
再びなりました)。
私の推測では、完全なタプルを使用する方がループの方が直感的ですが、を使用してメンバーシップをテストする場合はそうではないかもしれません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
、いくつかの点では、私はそれが非常だろうと言う巨大な矛盾。