web-dev-qa-db-ja.com

Pythonの+演算子と+ =演算子を使用した連結

最近、リストを連結しているときに不整合に気づきました。

したがって、+演算子を使用すると、リストが別のタイプのオブジェクトと連結されません。例えば、

l = [1,2,3]
l = l + (4,5)        #TypeError: can only concatenate list (not "Tuple") to list

しかし、+ =演算子を使用すると、オブジェクトのタイプが無視されます。例えば、

l = [1,2,3]
l += "he"            #Here, l becomes [1, 2, 3,"h", "e"]

l += (56, 67)        #Here, l becomes [1, 2, 3,"h", "e", 56, 67]

それで、それは単に言語の意味論なのか、それとも他の理由なのか?

38
Perspicacious

基本的な考え方は、+演算子と+=演算子は、Pythonでは必ずしも同じ操作ではなく、リストでは実際に異なるということです。 +操作は__add__マジックメソッドによって実行され、+=操作は__iadd__(インプレース追加)マジックメソッドによって実行されます。これらの魔法のメソッドは、演算子の左側の型から来ています。

リストのインプレース追加では、右側にリストを必要とせず、反復可能です。その後、アイテムはイテラブルから1つずつ取得され、リストに追加されます。これはリストのextendメソッドに似ています。したがって、+=演算子は、右側のオブジェクトのタイプを無視しない、それだけ使用できる可能なタイプ。

この動作はやや混乱します。私がこの問題について同様の(ただし重複していない)質問をするのを見たのは2日間で2人目だからです。ただし、この動作は便利です。リストを任意の反復可能オブジェクトと簡単に組み合わせることができるようになりました。

これについて詳しくは、 なぜPythonリストではタプルを+ =できないのに、タプルを+できないのですか? を参照してください。


@khelwoodのコメントにあるように、a += bの結果の型は明らかです。aの型です。したがって、bの型は柔軟にできます。結果のタイプのa + bは明確ではありません。 Pythonは厳密に型指定された言語であり、そのようなあいまいさを嫌います。- Zen of Python

明示的は暗黙的よりも優れています。

そして

あいまいな状況に直面して、推測する誘惑を拒否してください。

そして

実用性は純粋さを上回りますが。

したがって、現在の動作はPythonのZenに非常によく適合しています。 Zenには一貫性について何もないことに注意します。

41
Rory Daulton