pythonpython-3.xvariable-assignmentiterable-unpacking

python parallel assignment of 3 variables


My question is from a popular coding test.

Given a chain defined as follows:

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

If we want to revert the chain, for example:

Input:1->2->3->4->5->NULL

Output: 5->4->3->2->1->NULL

It can be solved like this:

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
        while cur:
            tmp = cur.next 
            cur.next = pre 
            pre = cur      
            cur = tmp     
        return pre

But there is a more compact way, which I can't really follow:

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
        while cur:
            cur.next, pre, cur = pre, cur, cur.next
        return pre

Because if I change the parallel assignment line to

            pre, cur, cur.next = cur, cur.next, pre

It wouldn't work properly anymore.

I am wondering how does the parallel assignment of python works, especially in the case that all 3 variables are dynamic.


Solution

  • When you write a parallel assignment

    x, y, z = a, b, c
    

    it's equivalent to

    temp = (a, b, c)
    x = temp[0]
    y = temp[1]
    z = temp[2]
    

    So in the failing version, it's equivalent to

    temp = (cur, cur.next, pre)
    pre = temp[0]
    cur = temp[1]
    cur.next = temp[2]
    

    Compare this to the working version:

    cur.next = temp[0]
    pre = temp[1]
    cur = temp[2]
    

    The difference is that in your version, you assign to cur.next after you've stepped cur to cur.next, so you're actually assigning to the original cur.next.next.