[Python-ideas] Unpacking iterables for augmented assignment

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Sun Aug 26 07:52:38 EDT 2018


James Lu writes:

 > I propose we apply PEP 3132 to PEP 203. That is, for every statement where
 > "<lhs> = <rhs>" is valid I propose "lhs += rhs" should also be
 > valid.
 > 
 > Simple example:
 > a = 0
 > b = 0
 > a, b += 1, 2
 > # a is now 1
 > # b is now 2

This isn't consistent with the normal behavior of Python sequences:

$ python3.6
>>> (1,2) + (3,4)
(1, 2, 3, 4)

That is, "+" means something different for sequences.  Furthermore,
the thing on the LHS is tuple syntax.  There's only one reasonable
meaning to give to an ordinary assignment from a sequence on the RHS
to a "tuple of variables".  But in your expression, the thing on the
LHS wants to be an object, which can only be a concrete tuple:

>>> a = 0
>>> b = 0
>>> a, b
(0, 0)

which is itself immutable, as are its integer components in your
example (which is not a toy, as complex expressions on the RHS would
mean you could only fit two, maybe three on a line, which doesn't save
much vertical space).  You can argue that the same would hold for
ordinary assignment, but doesn't, and that's true.  However, ordinary
assignment is a name-binding operation, while augmented assignment is
a mutation of the underlying object.  This is problematic for lists:

>>> [a, b] = 1, 2
>>> a, b
(1, 2)
>>> c = [1, 2]
>>> c += [3, 4]
>>> c
[1, 2, 3, 4]

I don't think the list syntax has any use different from the tuple
syntax.  The example of list syntax makes me uncomfortable, though.  I
wonder if there are traps with other mutable objects.

Finally, when I look at

 > a, b += 1, 2

as a once and future C programmer, I expect a value of

    (0, 1, 2)

to be printed, with a == 0, and b == 1 at this point.  (This is really
minor; we like to avoid confusion with carryovers from other
languages, but it's not enought to kill something useful.)

That said, none of the above is sufficient reason to reject a useful
syntax addition (augmented assignment to a tuple is currently an
error).  But it seems to me that compared to assignment by sequence
unrolling, this generalization isn't very expressive.  AIUI, one of
the motivations for unrolling sequence-to-sequence assignment in this
way is to provide the obvious notation for permutations:

>>> a, b = 1, 2
>>> b, a = a, b
>>> a, b
(2, 1)

and generalizing

>>> a, b, c, d, e = 1, 2, 3, 4, 5
>>> a, b, c, d, e = \
... e, a, b, c, d      # the values "move up", so a bit unintuitive
>>> a, b, c
(5, 1, 2)

You can't do any of the above without the sequence unrolling feature,
without adding temporary variables.

With augmented assignments, you can save some vertical space.  Is
there something else I'm missing?

Steve


More information about the Python-ideas mailing list