当我输入以下代码时,
x=[1,2,4]
print(x)
print("x",id(x))
x=[2,5,3]
print(x)
print("x",id(x))
它将输出显示为
[1, 2, 4]
x 47606160
[2, 5, 3]
x 47578768
如果列表是可变的,那么为什么在更改列表x时会给出2个内存地址?
答案 0 :(得分:14)
您没有使用以下行改变(更改)x
引用的列表对象:
x=[2,5,3]
相反,该行创建新列表对象,然后将变量x
重新分配给它。因此,x
现在引用了新对象,id(x)
给出了与之前不同的数字:
>>> x=[1,2,4] # x references the list object [1,2,4]
>>> x
[1, 2, 4]
>>> x=[2,5,3] # x now references an entirely new list object [2,5,3]
>>> x
[2, 5, 3]
>>>
答案 1 :(得分:13)
您创建了新列表对象,并将其绑定到同一名称x
。您从未在开始时突变绑定到x
的现有列表对象。
Python中的名称只是引用。赋值是将名称绑定到对象。再次分配给x
时,您将该引用指向其他对象。在您的代码中,您只需创建一个全新的列表对象,然后将x
反弹到该新对象。
如果你想 mutate 一个列表,请调用该对象的方法:
x.append(2)
x.extend([2, 3, 5])
或分配给列表的索引或切片:
x[2] = 42
x[:3] = [5, 6, 7]
演示:
>>> x = [1, 2, 3]
>>> id(x)
4301563088
>>> x
[1, 2, 3]
>>> x[:2] = [42, 81]
>>> x
[42, 81, 3]
>>> id(x)
4301563088
我们更改了列表对象(变异了),但该列表对象的id()
没有改变。它仍然是相同的列表对象。
也许Ned Batchelder关于Python名称和绑定的精彩演示可以提供帮助:Facts and myths about Python names and values。
答案 2 :(得分:4)
您没有改变列表,而是创建新列表并将其分配给名称x
。这就是id
为您提供不同输出的原因。你的第一个清单已经消失,将被垃圾收集(除非在某处有另一个参考)。