我真的很难理解指向类的指针是如何工作的。假设我们有一个链表中的节点:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
然后,如果我们创建一个指向
x
的指针并创建另一个节点 y
并将其分配给 x.next
,我们将能够在指针中保留 x.val
并在 y
属性中拥有 .next
:
x = ListNode(3)
headNode = x
y = ListNode(4)
x.next = y
print(f'ID of y: {id(y)}')
print(f'Current x.next:\n\t.val: {x.next.val}\t.next:{x.next.next},\ncurrent headNode.next.next: {headNode.next.next}\n')
打印出:
ID of y: 2656509108560
Current x.next:
.val: 4 .next:None,
current headNode.next.next: None
现在如果我们做同样的事情并再次替换
x
中的属性,指针将自动添加另一个节点到 .next
的 .next
属性:
x = y
y = ListNode(4)
x.next = y
print(f'ID of y: {id(y)}')
print(f'Current x.next:\n\t.val:{x.next.val}\t.next:{x.next.next},\ncurrent headNode.next.next: {headNode.next.next.val}\n')
x = y
print(f'Cached list: [{headNode.val}] -> [{headNode.next.val}] -> [{headNode.next.next.val}]')
打印出:
ID of y: 2656507051616
Current x.next:
.val:4 .next:None,
current headNode.next.next: 4
Cached list: [3] -> [4] -> [4]
我想知道这种行为(自动填充指针
next.next
内的headNode
属性从None
到另一个ListNode
)是否是由Python自动理解它指向唯一实例(id(y)
不同)引起的因此寻址它可以在类中找到的另一个 .next
指针。如果有人能帮助我解决这个问题,我将非常感激。预先感谢。
简短的回答是没有自动填充属性。在每一点上,您都自己设置属性,并且指针仅指向您手动创建的内容。
让我们看看您的代码,并将我们自己的“内存 ID”分配为“第一”、“第二”和“第三”。在每个块之后,我们都会问自己同样的三个问题。 x.下一个是什么?什么是 x.next.next?什么是 headNode.next.next?每次答案都会指向我们手动实例化和设置的节点。
第一块:
x = ListNode(3) # x = First
headNode = x # headNode = First
y = ListNode(4) # y = Second
x.next = Y # First.next = Second
x.next 是什么?好吧,我们知道 x 指向 First,并且我们将 First.next 设置为 Second。因此 x.next 是 Second,我们将其创建为值为 4 且 next 为 None 的 ListNode。
x.next.next 是什么?我们知道 x.next 是 Second。我们没有为 Second.next 设置任何内容,因此它采用 ListNode 构造函数设置的默认值 None,因此 x.next.next 为 None。
什么是 headNode.next.next?我们知道headNode指向First。 First.next 是 Second。所以 First.next.next 是 Second.next。第二个.下一个是无。
下一个区块:
x = y # x = Second
y = ListNode(4) # y = Third
x.next = y # Second.next = Third
x.next 是什么?现在 x 指向 Second,然后我们将 Second.next 设置为 Third。所以 x.next 现在是第三个。
x.next.next 是什么?这是 Third.next,即 None。
什么是 headNode.next.next? headNode 仍然指向 First。 First.next 是 Second。第二.下一个是第三。所以 First.next.next 是 Third,因此 headNode.next.next 是 Third。
我再次重申,在每个实例中,您都在引用您手动创建或设置的内容。
不,它不会自动填充
next.next
,这种行为是因为你设置了x = y
,使得x
引用了与y
相同的对象。
x = ListNode(3)
headNode = x
y = ListNode(4)
x.next = y
print(f'ID of old y: {id(y)}')
x = y
y = ListNode(4)
x.next = y
print(f'ID of headNode.next: {id(headNode.next)}')
print(f'ID of x: {id(x)}')
print(f'ID of y: {id(y)}')
输出:
ID of old y: 139130971403312
ID of headNode.next: 139130971403312
ID of x: 139130971403312
ID of y: 139130971402976
请注意,
headNode.next
和 x
与旧的 y
具有相同的 id。当您设置 x.next = y
时,它相当于 headNode.next.next = y
,因为 x
现在引用 headNode.next
。