考虑以下示例代码
class Node:
def __init__(self, value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return str(self.value)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node5 = node1
node1.next = node2
node2.next = node3
#node5 = node1
def printList(node):
while node:
print(node)
node = node.next
printList(node1)
printList(node5)
(示例来自https://blog.csdn.net/qq_39422642/article/details/78988976)我把node5 = node1
放在node1.next之前。然而,在printList(node5)
中,它给出了与printList(node1)
相同的结果。为什么node5即使在建立链表之前给出了值,也会保持链表的结构?
如果我使用正常变量
a = 3
b = a
a = 2
print(a,b)
结果是2,3。与第一块中的链表示例相反,b=a
将不受代码本身之后的代码的影响。非常感谢。
因为在Python中,变量存储引用(而不是值(。语句node5 = node1
实际上使node5
指向一个对象。CCD_ 7也指向相同的对象。如果使用node1
或node5
更改该对象,并使用node1
或node5
打印结果,则会打印相同的结果。
使用int
观察到的不同行为是因为int
在Python中是不可变的。如果更改对象的值,python将创建一个不同的对象,将新值存储在其中,并更新b
以指向该对象(b = a
(。在该语句之后,a
将仍然指向具有值2
的旧对象。如果您使用Python中的任何一个不可变代码尝试您的第二个代码,您将得到相同的结果。
如果要将node1复制到node5,请使用deepcopy:
import copy
class Node:
def __init__(self, value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return str(self.value)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = node1
node5 = copy.deepcopy(node1)
node1.next = node2
node2.next = node3
def printList(node):
while node:
print(node, end=" ")
node = node.next
print("")
print("Node1 Id", id(node1), end=" ")
printList(node1)
print("Node4 Id", id(node4), end=" ")
printList(node4)
print("Node5 Id", id(node5), end=" ")
printList(node5)
输出:
Node1 Id 140465951784072 1 2 3
Node4 Id 140465951784072 1 2 3
Node5 Id 140465951810560 1
编辑:
根据@user3159253的建议,在我的回答中添加了id((。您可以看到node1
返回的id()
和node4
是相同的。这意味着,它们确实指向同一个对象,并且使用任何一个变量(node4或node1(进行的任何更改都将更改同一个单个对象,因此,如果使用node1或node4打印,则会得到相同的结果。
但是,如果您尝试使用id()
:的第二个代码
a = 2
b = a
print("Id of a", id(a), "Value of a", a)
print("Id of b", id(b), "Value of b", b)
a = 5
print("Id of a", id(a), "Value of a", a)
print("Id of b", id(b), "Value of b", b)
输出:
Id of a 10914528 Value of a 2
Id of b 10914528 Value of b 2
Id of a 10914624 Value of a 5
Id of b 10914528 Value of b 2
正如您所看到的,在分配b = a
、a
和b
后,它们指向同一个对象,但一旦您将a
的值重新分配为5,python就会创建不同的对象(因此,id((返回不同的值(,并将a
更改为指向值为5的对象。它这样做是因为int
在Python中是不可变的。