Python - Tricky Parts You Never Thought About: Multiple Assignment

May 11, 2020

In solving the problem 206. Reverse Linked List I noticed a weird behavior in python.

Usually, we solve it like this:

    def reverseList(self, head: ListNode) -> ListNode:
        prev, cur = None, head
        while cur:
            nextTemp = cur.next
            cur.next = prev
            prev = cur
            cur = nextTemp
        return prev

It's possible to use multiple assignment to make it one line:

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

Here's the catch. If I change the 4th line to

curr, prev, curr.next = curr.next, curr, prev

I get this error:

'NoneType' object has no attribute 'next'

Why is this? Aren't the 3 assignment supposed to happen at the same time?

As it turns out, the issue was with how multiple assignments on the same line work. These assignments actually don't happen at the same time. Let me explain how it works.

First, the values on the right side are evaluated as a tuple. i.e. (curr.next, curr, prev). No problem up to this point.

The issue is on the left side. With the right side evaluated, python unpacks the tuple and assigns the values to the variables on the left IN ORDER, with the variables being (curr, prev, curr.next). See the problem now? curr is updated before curr.next is updated, so curr may be set to None before prev is assigned to cur.next.

Subscribe to my email list

© 2024 ALL RIGHTS RESERVED