Search code examples
pythonlistlinked-listreferencevariable-assignment

Why are the results different depending on how to assign?


When I tried to reverse the Linked list, I noticed that the results varied depending on how I did the assignments.

Why does it happen as bellow?

class ListNode:
    def __init__(self, val=0, next: Optional["ListNode"] = None):
        self.val = val
        self.next = next


# It works as expected with unpacking assignment.
nodes = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
rev = None
while nodes is not None:
    rev, rev.next, nodes = nodes, rev, nodes.next
# rev = [5, 4, 3, 2, 1]

# But dose not work as expected when assigning one by one.
cnt = 0
nodes = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
rev = None
while nodes is not None:
    if cnt > 10:
        break
    rev = nodes
    rev.next = rev
    nodes = nodes.next
    cnt += 1
# rev = [1, 1, 1, 1, 1...] Infinite loop in circular reference!

My Environments:

  • Python 3.10.7

Thanks a lots.


Solution

  • What applies here is

    rev, rev.next, nodes = nodes, rev, nodes.next
    

    the right-hand expression is evaluated before the left-hand assignement. So you assign nodes.next to nodes and rev to rev.next. That's why it is correct.

    In the second loop. You killing the link here

    rev.next = rev
    

    after this it can not stop