3

Is there a reason that assigning a list to another list and changing an item in one reflects the change in both, but changing the entire list of one does not reflect the change in both?

a=5
b=a
a=3
print b #this prints 5

spy = [0,0,7]
agent = spy
spy[2]=8
print agent #this prints [0,0,8]

spy = [0,0,7]
agent = spy
spy = "hello"
print agent #this prints [0,0,7]
4

3 回答 3

7

Your first mutates the object, your second rebinds the name.

(list that spy contains)[2]=8

(name called "spy")= "hello"

于 2012-04-21T21:16:17.943 回答
2

如果您忘记了有关指针、地址、值传递和引用传递的所有知识,而将其视为标签和对象,或者名称和对象,那么 Python 中的引用会更容易理解。

按照这个:

a=5
b=a
a=3
print b #this prints 5

你有标签'a'放在5上,然后'b'放在同一个对象'a'上,因此是5。然后'a'被移除并放在3上。'b'仍然在5上并移动'a'到别的东西不影响它。

spy = [0,0,7]

您将名称“间谍”放在列表中 [0, 0, 7]

agent = spy

您将名称“代理”放在同一个列表中 [0, 0, 7]

spy[2]=8
print agent #this prints [0,0,8]

您将列表中的索引 2 标签放在 8 上。由于 agent 和 spy 都是同一个列表的名称,因此当您打印它时,您会看到两者的变化。

spy = [0,0,7]

您在列表 [0, 0, 7] 上有名称“间谍”

agent = spy

您在同一个列表 [0, 0, 7]上有名称“代理”

spy = "hello"

现在你已经从列表中删除了名字'spy'并放入了一个字符串“hello”。该列表仍然具有分配给它的标签“代理”。

print agent #this prints [0,0,7]

知道了?

于 2012-04-21T21:30:42.360 回答
1

当您将一个列表分配给一个变量到另一个变量时,它们都属于同一个列表。

spy = [0,0,7]
agent = spy
spy[2]=8

所以这就是为什么你改变 spy 所以代理也改变了,因为它们都属于同一个内存位置上的同一个列表。你可以检查一下

id(spy)
id(agent)

这是通过引用调用。

但是如果在代理初始化后将新列表分配给 spy,则 spy 属于另一个内存位置上的另一个列表。

id(spy)
id(agent)

您还可以使用 id() 函数检查这一点,该函数提供内存中变量的引用 ID。

于 2012-10-01T11:21:34.257 回答