>>> r = [[]]
>>> r[0] = r[0] + 'abc'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
>>> r[0] += 'abc'
>>> r
[['a', 'b', 'c']]
有人可以解释为什么第二个作业有效但第一个作业无效吗?
您首先初始化数组array。>>> r = [[]]
然后在下面提到的步骤中,您尝试添加两种不同类型的元素并将其分配给r列表的零索引。即一个是列表(即r[0]
,它是空数组[]),另一个是字符串('abc')
>>> r[0] = r[0] + 'abc'
因此您将看到以下错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
下面的代码中,您正在将值分配给索引为零的空数组。这意味着您正在更新r
的零索引,即从[[]]更新为[['a','b','c']]。
>>> r[0] += 'abc'
>>> r
[['a', 'b', 'c']]
为什么+=
有效而+
不起作用是“这就是它的编码方式”。但是我还没有找到任何充分的理由。让我们只关注列表添加
operator magic method list equiv
-------- ------------ ----------
+= (inplace add) __iadd__ list_inplace_concat
+ (add) __add__ list_concat
Inplace Add / list_inplace_concat适用于任何序列。在幕后,python只需调用list.extend
即可将右侧变成迭代器,因此适用于所有序列
>>> test = []
>>> test += 'abc'
>>> test
['a', 'b', 'c']
添加/ list_concat被硬编码为仅与其他列表一起使用。底层的C代码使用列表的内部数据结构来复制其元素。
>>> test + 'abc'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
将右侧更改为列表即可使用
>>> test + list('abc')
['a', 'b', 'c', 'a', 'b', 'c']
>>>
list_concat
经过优化,可以使用两个列表的大小来确切知道新列表需要多大。然后,它在C结构级别进行成员复制。让我感到困惑的是,为什么在检测到“未列出”条件时就没有回退。该列表可以复制和扩展。