6

Python (2.7) でこれまで言及されたことのない興味深いことが見つかりました。

これ:

a = []
a += "a"

動作し、結果は次のとおりです。

>>> a
>>> ["a"]

しかし

a = []
a = a + "a"

与える

>>> TypeError: can only concatenate list (not "str") to list

誰かが理由を説明できますか?回答ありがとうございます。

4

2 に答える 2

11

+Python は演算子と演算子を区別し+=、これらに個別のフックを提供します。__add____iadd__。このlist()型は、後者に対して異なる実装を提供するだけです。

リストがこれらを別々に実装する方が効率的です。__add__は完全に新しいリストを返す必要がありますが、__iadd__拡張してから返すことができselfますself

C コードで__iadd__は、 によって実装されlist_inplace_concat()ます。これは単に を呼び出すlistextend()か、Python コードでは を呼び出します[].extend()。後者は、設計上、任意のシーケンスを取ります。

__add__一方、C で によって表されるメソッドは、おそらく効率のために、入力としてlist_concata のみを受け取ります。list内部 C 配列を直接ループして、アイテムを新しいリストにコピーできます。

結論として、__iadd__任意のシーケンスを受け入れる理由は、PEP 203 (Augmented Add 提案) が実装されたとき、リストについては.extend()メソッドを再利用するのが最も簡単だったからです。

于 2012-12-16T18:13:19.703 に答える
9

aがリストの場合、 もリストの場合にのみ機能a + xしますが、 iterable の場合は機能します。xa += xx

以下はそれを理解するのに役立つかもしれません:

In [4]: a = []

In [5]: a += "abc"

In [6]: a
Out[6]: ['a', 'b', 'c']

重要なのは、"a""abc"が反復可能であることです。これにより、 の右側で使用できるようになります+=

+後者では両方のオペランドが同じ型である必要があるため、これは機能しません(マニュアルを参照)。

を使用して同じことを記述するには+、イテラブルを展開する必要があります。

In [7]: a = []

In [8]: a = a + list("abc")

In [9]: a
Out[9]: ['a', 'b', 'c']

つまり、リストに適用される場合+=よりも一般的です。+

于 2012-12-16T18:06:03.337 に答える