python列表连接中的奇怪行为

2024-04-20 09:29:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个Python列表

>>> list1 = ['a', 'b', 'c']

然后设置

^{pr2}$

现在我执行两个类似的操作list1和{}

>>> list1 = list1 + [1, 2, 3]
>>> list1
['a', 'b', 'c', 1, 2, 3]
>>> list2
['a', 'b', 'c']

以及

>>> list2 += [1,2,3]
>>> list1
['a', 'b', 'c', 1, 2, 3]
>>> list2
['a', 'b', 'c', 1, 2, 3]

但这两种情况的结果是不同的。原因是什么?在


Tags: 列表情况原因list2list1pr2
3条回答

Python中用于列表的+=运算符实际上在内部调用了list.extend()函数,因此列表得到了适当的扩展。在

而当我们执行+连接运算符时,会创建并返回一个新的列表,因此list1中的实际列表没有更改,而是{}现在指向一个新列表。在

这是因为第一个操作将一个新对象分配给list1,而第二个操作则是更改分配给list2的原始对象。在

如果使用id()检查分配给变量的对象的id,则更容易理解:

>>> list1 = ['a', 'b', 'c']
>>> id(list1)
4394813200
>>> list2 = list1
>>> id(list2)
4394813200 # same id
>>> list1 = list1 + [1, 2, 3]
>>> id(list1)
4394988392 # list1 now references another object
>>> list1
['a', 'b', 'c', 1, 2, 3]
>>> id(list2)
4394813200 # list2 still references the old one
>>> list2
['a', 'b', 'c']
>>> list2 += [1,2,3]
>>> id(list2)
4394813200 # list2 still references the old one
>>> list2
['a', 'b', 'c', 1, 2, 3]
>>> id(list1)
4394988392
>>> list1
['a', 'b', 'c', 1, 2, 3]

这背后的原因是+=+调用了类的两个不同方法,^{} method和{a2}。在

从API的角度来看,iadd应该被用来就地修改可变对象(返回被改变的对象),而add应该返回某个新的实例。对于不可变对象,这两个方法都返回一个新实例,但是iadd会将新实例放在当前名称空间中,其名称与旧实例的名称相同。这就是原因

i = 1
i += 1

实际上,你得到了一个新的整数并把它赋给“在”i之上——失去了对旧整数的一个引用。在本例中,i+=1与i=i+1完全相同。但是,对于大多数可变对象,情况就不同了:

例如:

^{pr2}$

与之相比:

a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]

注意在第一个例子中,因为b和a引用了同一个对象,所以当我在b上使用+=时,它实际上改变了b(a也看到了这种变化——毕竟,它引用的是同一个列表)。然而,在第二种情况下,当我使用b=b+[1,2,3]时,这将获取b正在引用的列表,并将其与一个新列表[1,2,3]连接起来。然后,它将连接后的列表存储在当前名称空间中,而不考虑前面的行是什么。在

相关问题 更多 >