Search code examples
pythonpython-3.xiterable-unpacking

Why is the result different if I switch the sequence in setting variables by common?


To explain better, I wrote a small class node, and set a and b:

class node(object):
    def __init__(self,x,y):
        self.val = x 
        self.next = y

a = node(5,6)
b = None

Then I found the result is different between:

a, a.next, b = a.next, b, a
print(a,b)  #it returns AttributeError: 'int' object has no attribute 'next'

and:

a.next, a, b = b, a.next, a
print(a,b)  #it returns 6 <__main__.node object at 0x1021a0400>

We all know, when a, b = b, a+b, it gives a,b value simultaneously, and the result doesn't change when the code becomes b, a = a+b, b.

So, could anybody help me with it? Why does this happen?


Solution

  • The unpacking isn't simultaneously. It's just that the right hand side is "constructed" before it's "unpacked" into the left hand side. But each side is evaluated left-to-right!

    So what happens is roughly like this (it actually doesn't build the tuple but that's just an implementation detail):

    tmp = (a.next, b, a)
    a = tmp[0]
    a.next = tmp[1]  # fails because "a" is now an integer
    b = tmp[2]
    

    In the second case it works because is "re-assigned" after "re-assigning" a.next:

    tmp = (b, a.next, a)
    a.next = tmp[0]  # a still has the next attribute
    a = tmp[1]
    b = tmp[2]