列表扩展奇怪的行为

时间:2012-12-16 18:04:28

标签: python list

在Python(2.7)中发现了前所未有的有趣之处。

此:

a = []
a += "a"

确实有效,结果是:

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

但是

a = []
a = a + "a"

给出

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

有人可以解释原因吗?谢谢你的回答。

2 个答案:

答案 0 :(得分:11)

Python区分++=运算符,并为这些运算符提供单独的挂钩; __add____iadd__list()类型只为后者提供了不同的实现。

列表分别实现这些更有效; __add__必须返回一个全新的列表,而__iadd__只能扩展self,然后返回self

在C代码中,__iadd__list_inplace_concat()实现,它只调用listextend(),或者在python代码中调用[].extend()。后者按设计采用任何序列。

另一方面,__add__方法用C list_concat表示,只需要list作为输入,可能是为了效率;它可以直接在内部C数组上循环,并将项目复制到新列表。

总之,__iadd__接受任何序列的原因是因为实施PEP 203(增强添加提案)时,对于列表来说,最简单的方法是重用.extend()方法。 / p>

答案 1 :(得分:9)

如果a是一个列表,a + x仅在x也是列表的情况下有效,而a += x适用于任何可迭代的x。< /强>

以下内容可能有助于理解它:

In [4]: a = []

In [5]: a += "abc"

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

关键是"a""abc"是可迭代的,这使得它们可以在+=的右侧使用。

这对+不起作用,因为后者要求两个操作数属于同一类型(请参阅manual)。

要使用+编写相同的内容,您必须扩展iterable:

In [7]: a = []

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

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

换句话说,+=在应用于列表时比+更通用。