>>> L = [4, 5, 6]
>>> X = L * 4
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> L[1] = 0
为什么
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
而不是
>>> X
[4, 0, 6, 4, 0, 6, 4, 0, 6, 4, 0, 6]
什么?你知道吗
当L * 4
被求值时,调用什么函数或方法?你知道吗
L.copy()
list(L)
copy.copy(L)
- 或者别的什么?你知道吗
谢谢。你知道吗
Tags:
调用
L * 4
时,调用的引擎盖下的机器类似于以下Python代码:这意味着每个元素都是对原始元素的引用,但会创建一个新的列表对象。它和
L.copy()
、list(L)
、或copy.copy(L)
都不一样。你知道吗让我们看看这是如何在引擎盖下实现的。下面是遇到
*
运算符时在CPython中发生的情况:在} (这是一种过于简单的操作,有关详细信息,请参阅第一条注释)。这是密码
PyNumber_Multiply
函数中,如果数字乘法失败,它会假定其中一个对象是序列,因此(经过一段间接寻址之后)最终调用^{如您所见,它首先分配一个新列表,然后将列表中的每个对象的引用放到新列表中,而不是简单地创建几个原始对象的引用。因此,列表中的每个元素都是对原始元素的引用,但列表本身并不是对原始元素的引用。你知道吗
它不复制引用。请参见:
没有修改
X
的原因是语法糖是用来
__mul__
函数是Python在使用*
操作符时在后台调用的函数。它返回一个新对象:因此
X
保存对L.__mul__(4)
返回的新对象的引用,而不是对L
正在引用的对象的引用。基本上,X
和L
引用完全不同的列表对象,因此更改一个变量引用不会影响另一个变量引用请注意,虽然Python不会复制
L
所持有的引用,但它会创建对L
引用的列表对象中的每个元素的引用的副本。这就是为什么子列表相乘会导致意外行为:相关问题 更多 >
编程相关推荐