2

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.

  • The link you shared does explain what you got. That said, avoid tuple-style assignment when working with these data structures. Python is not the only language out there. There will be some day you need to write code in other languages. You may have a co-worker coming from java. These caveats will drive your mentality nuts. Stay will the old-school way of assignment line by line. – Bing Wang Apr 18 '21 at 02:57
  • I only read some sentences in the beginning of that link. The remaining part is difficult to understand. – otakutyrant Apr 18 '21 at 03:29

1 Answers1

2

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
Prune
  • 76,765
  • 14
  • 60
  • 81
  • I thought every assignment of the left-hand side is guaranteed to be isolated from one another. `a, b = b, a` caused me such a fatal delusion. It was kind of you to tolerate my foolish. – otakutyrant Apr 18 '21 at 03:45