清单+字符串在Python 3.7.6中的行为不一致

问题描述 投票:0回答:2
>>> 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']]

有人可以解释为什么第二个作业有效但第一个作业无效吗?

python python-3.x list append
2个回答
0
投票

您首先初始化数组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']]

0
投票

为什么+=有效而+不起作用是“这就是它的编码方式”。但是我还没有找到任何充分的理由。让我们只关注列表添加

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结构级别进行成员复制。让我感到困惑的是,为什么在检测到“未列出”条件时就没有回退。该列表可以复制和扩展。

© www.soinside.com 2019 - 2024. All rights reserved.