Skip to content Skip to sidebar Skip to footer

Python Assignment Quirk W/ List Index Assign, Dict Index Assign, And Dict.get

In ruby 2.4: x = ['a'] y = {} x[0] = y[x[0]] = y.fetch(x[0], y.length) puts y #=> {'a'=>0} In python 3.5: x = ['a'] y = {} x[0] = y[x[0]] = y.get(x[0], len(y)) print(y) #=&g

Solution 1:

Ruby and Python are different languages, and make different choices. In Python assignments are statements and evaluates multiple assignment targets from left to right. Ruby made other choices; assignments are expressions and as a result are evaluated in the opposite order.

So in Ruby this happens:

  • Evaluate y.fetch(x[0], y.length), produces 0 (key is missing, y is empty).
  • Evaluate y[x[0]] = 0, so y['a'] = 0. This is an expression resulting in 0.
  • Evaluate x[0] = 0 (0 being the result of the y[x[0]] = 0 assignment expression).

Note that in Ruby, an assignment is an expression. It can be nested inside other expressions, and the result of the assignment expression is the value of the target after assignment.

In Python this happens instead:

  • Evaluate y.get(x[0], len(y)), produces 0 (key is missing, y is empty).
  • Evaluate x[0] = 0.
  • Evaluate y[x[0]] = 0, so y[0] = 0.

From the Python assignment statements documentation:

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

So the expression on the right-hand-side is evaluated first, and then assignment takes place to each target from left to right.

Python made assignments statements on purpose, because the difference between:

if a = 42:

and

if a == 42:

is so damn hard to spot, and even if intentional really hurt the readability of code. In Python, readability counts. A lot.

Generally speaking, you really want to avoid making assignments to names that are then also used in subsequent assignments in the same statement. Don't assign to x[0] and then use x[0] again in the same assignment, that's just hugely confusing.


Post a Comment for "Python Assignment Quirk W/ List Index Assign, Dict Index Assign, And Dict.get"