An asssigment of a linked list does not work as expected

Viewed 40

I posted What is wrong with my code? a month ago. No answers. Now I decide to study this issue again. I simplified the reproducibe code here:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

c = ListNode(val=3)
b = ListNode(val=2, next=c)
a = ListNode(val=1, next=b)
node = a
print(node.val)
print(node.next.next.val)
node, node.next = node.next, node.next.next # This is the assignment that does not work.
print(a.val)
print(a.next.val)
print(node.val)

After the assignment, a.next.val should be 3, but it is 2. If I change the assignment as below:

tmp_node = node.next
node.next = node.next.next
node = tmp_node

a.next.val becomes 3 at last.

So why does the first assignment statement not work well?

How does swapping of members in tuples (a,b)=(b,a) work internally? points out that the values of the right expression are isolated from the left one.

1 Answers

You haven't explained how you expect that the assignment will produce the result you claim. I suspect that you expect node.next to resolve differently from the formal definition.

If you resolve the node references to their single-letter equivalents, the sequence of assignments looks something like this:

### node, node.next = node.next, node.next.next
### -------------------------------------------
temp1 = a.next      # which is b
temp2 = a.next.next # which is b.next, which is c
node = temp1        # which is b
node.next = c       # which is b.next = c

Note this last line: the first part of the multiple assignment changes the value of node: node.next refers to b.next, not a.next. For the result you expect, you need to reverse the assignment:

node.next, node = node.next.next, node.next
Related