Python 奇怪的行为:“+=”创建别名
Python strange behavior: "+=" creates aliases
我无法解释这段代码的行为:
n=[[0,0],[0,0]]
m=n.copy()
for i in range(len(m)):
m[i]+=[0]
我得到的输出是(不是我预期的):
>>> m
[[0, 0, 0], [0, 0, 0]]
>>> n
[[0, 0, 0], [0, 0, 0]]
如果我改为输入:
n=[[0,0],[0,0]]
m=n.copy()
for i in range(len(m)):
m[i]=m[i]+[0]
我得到了正确的输出(这是我最初的预期):
>>> m
[[0, 0, 0], [0, 0, 0]]
>>> n
[[0, 0], [0, 0]]
所以,看起来如果我使用“+=”快捷方式,两个矩阵 "m" 和 "n" 就会变成别名。有人可以解释为什么会这样吗?
n.copy()
创建浅拷贝,因此 n[i]
和 m[i]
已经指向同一个对象(尽管 m
和 n
不同) .
对于列表,x += y
与 x = x + y
完全不同 - 前者直接变异 x
(相当于 x.extend(y)
) 而后者将 x
分配给一个新值。
这两个事实共同解释了这种行为。
这里的区别在于 some_list += some_iterable
实际上与 some_list.extend(some_iterable)
相同。
some_list = some_list + [something_else]
实际上从 some_list
和 [something_else]
连接在一起创建了一个新列表,然后将该新列表分配回 =
运算符的左侧.
当你这样想的时候,并且知道在复制之后,m[idx] is n[idx]
for all 0 <= idx < len(m)
1,就更容易明白为什么了+=
版本更改同时出现在 m
和 n
.
中
1list.copy()
进行 shallow 复制——这意味着它只复制引用。
我无法解释这段代码的行为:
n=[[0,0],[0,0]]
m=n.copy()
for i in range(len(m)):
m[i]+=[0]
我得到的输出是(不是我预期的):
>>> m
[[0, 0, 0], [0, 0, 0]]
>>> n
[[0, 0, 0], [0, 0, 0]]
如果我改为输入:
n=[[0,0],[0,0]]
m=n.copy()
for i in range(len(m)):
m[i]=m[i]+[0]
我得到了正确的输出(这是我最初的预期):
>>> m
[[0, 0, 0], [0, 0, 0]]
>>> n
[[0, 0], [0, 0]]
所以,看起来如果我使用“+=”快捷方式,两个矩阵 "m" 和 "n" 就会变成别名。有人可以解释为什么会这样吗?
n.copy()
创建浅拷贝,因此 n[i]
和 m[i]
已经指向同一个对象(尽管 m
和 n
不同) .
对于列表,x += y
与 x = x + y
完全不同 - 前者直接变异 x
(相当于 x.extend(y)
) 而后者将 x
分配给一个新值。
这两个事实共同解释了这种行为。
这里的区别在于 some_list += some_iterable
实际上与 some_list.extend(some_iterable)
相同。
some_list = some_list + [something_else]
实际上从 some_list
和 [something_else]
连接在一起创建了一个新列表,然后将该新列表分配回 =
运算符的左侧.
当你这样想的时候,并且知道在复制之后,m[idx] is n[idx]
for all 0 <= idx < len(m)
1,就更容易明白为什么了+=
版本更改同时出现在 m
和 n
.
1list.copy()
进行 shallow 复制——这意味着它只复制引用。