3

I have recently started learning python. I was playing around with simultaneous assignments today and came across some results that were produced by my code that I cannot understand.

x, y = 3, 5
x, y = y, (x+y)
print(y) 

The output is 8.

I am not understanding why y = 8 instead of y = 10 despite x = y = 5 being evaluated first. Since y = 8, this tell us that x = 3 when y = x + y is being evaluated ? How is that possible if x = y is first evaluated, since it is evaluated left to right ?

I first debugged the code (which produced the same result), which I cannot understand. I also have tried looking at the python documentation, where it states "simultaneous overlaps within the collection of assigned-to variables occur left-to-right, sometimes resulting in confusion." The example that it presents follows my logic:

x = [0, 1]
i = 0
i, x[i] = 1, 2         
print(x)

It outputs 2.

(Evaluated left to right) Since i is updated to 1. Then, this updated i is used and hence, x[1] = 2 not x[0] = 2.

I really would appreciate some help.

kalehmann
  • 4,821
  • 6
  • 26
  • 36
David
  • 98
  • 5

2 Answers2

3

I am not understanding why y = 8 instead of y = 10 despite x = y = 5 being evaluated first

The right side of an assignment is evaluated first.

In your assignment with x = 3 and y = 5

x, y = y, (x+y)

the right side is evaluated to a tuple (5, 8) first and then assigned to the values on the left side. Therefore y is 8.

You could also think of it as

x, y = 3, 5
temp = y, x + y
x, y = temp

To see what really happens internal, you can disassemble your code:

>>> import dis
>>> def f(x, y):
...     x, y = y, x + y
...
>>> dis.dis(f)

Outputs

  2           0 LOAD_FAST                1 (y)
              2 LOAD_FAST                0 (x)
              4 LOAD_FAST                1 (y)
              6 BINARY_ADD
              8 ROT_TWO
             10 STORE_FAST               0 (x)
             12 STORE_FAST               1 (y)
             14 LOAD_CONST               0 (None)
             16 RETURN_VALUE

As you can see, the addition is performed before the assignment.

kalehmann
  • 4,821
  • 6
  • 26
  • 36
0

Python goes right-to-left, left-to-right. You can imagine that python pushes its operations to a stack-like data structure.

Looking at the first assignment: x, y = 3, 5

  1. python will first push the right-hand side value onto the stack as a tuple.

  2. run an unpacking-sequence for n values from the stack, and puts the values back onto the stack right-to-left. "push 5 to the stack, then 3". Current stack = [3, 5]

  3. Finished with the right-hand side, python will assign values to the left-hand side left-to-right, while removing top-of-stack. So it will first tak 3 and store it in variable x, then 5 and store it in variable y.

You can inspect the operations python does in byte code using the dis module.

python byte-code for assignment x, y = 3, 5

The following assignments:

x, y = 3, 5
x, y = y, (x + y)

Produce the following operations:

left to right assignment operations

You can inspect the bytecode operations here: http://pyspanishdoc.sourceforge.net/lib/bytecodes.html

Kent Martin
  • 225
  • 2
  • 10