11

Consider the following Python 3 code:

a = [-1,-1,-1]
i = 0

And now consider the following two versions of a simultaneous assignment over both a and i:

Assignment version 1:

a[i],i = i,i+1

Assignment version 2:

i,a[i] = i+1,i

I would expect these two versions of simultaneous assignments to be semantically equivalent. However, if you check the values of a and i after each one of the simultaneous assignments, you get different states:

Output for print(a,i) after assignment version 1:

[0, -1, -1] 1

Output for print(a,i) after assignment version 2:

[-1, 0, -1] 1

I am not an expert on Python's semantics, but this behaviour seems weird. I would expect both assignments to behave as assignment version 1. Moreover, if you check the following link, one would expect both assignment versions to lead to the same state:

Link to book excerpt in Google Books

Is there something I am missing regarding Python semantics for simultaneous assignments?

Note: This weird behaviour does not seem to be reproducible, for instance, when the variable a has integer type; it seems to require a to be of type list (maybe this is the case for any mutable type?).

hquilo
  • 123
  • 1
  • 5

1 Answers1

12

In this case:

i, a[i] = i + 1, i

The righthand side evaluates to a tuple (1, 0). This tuple is then unpacked to i and then a[i]. a[i] is evaluated during the unpacking, not before, so corresponds to a[1].

Since the righthand side is evaluated before any unpacking takes place, referring to a[i] on the righthand side would always be a[0] regardless of the final value of i

Here is another useless fun example for you to work out

>>> a = [0,0,0,0]
>>> i, a[i], i, a[i] = range(4)
>>> a
[1, 0, 3, 0]
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Thank you gnibbler, I see the technical point you raise about the evaluation to tuples; from that point of view all makes perfect sense. However, I am still at a loss from a semantics viewpoint since then the _simultaneous_ assignment semantics is then not very simultaneous. Since I am new to Python, I would take my chances and ask if there is an official document with a formal/semi-formal definition of the assignment semantics for Python. Are you aware of any such a document? – hquilo May 07 '13 at 01:53
  • 3
    @hquilo: "simultaneous assignment" doesn't even appear in the Python documentation. `a, b = 1, 2` is just shorthand for `(a, b) = (1, 2)`, which is called sequence unpacking. – Blender May 07 '13 at 02:01
  • Thank you both @gnibler and @Blender; your answers make things clear. – hquilo May 07 '13 at 02:11
  • Just to add a reference to the documentation (https://docs.python.org/3/reference/simple_stmts.html): "Although the definition of assignment implies that overlaps between the left-hand side and the right-hand side are ‘simultaneous’ (for example `a, b = b, a` swaps two variables), overlaps _within_ the collection of assigned-to variables occur left-to-right, sometimes resulting in confusion." – Kurt Peek Dec 07 '17 at 06:09