[Python-ideas] Unpacking iterables for augmented assignment

Steven D'Aprano steve at pearwood.info
Sun Aug 26 21:40:31 EDT 2018


On Sun, Aug 26, 2018 at 07:50:49PM +0100, Jonathan Fine wrote:
> Hi James and Steve
> 
> Myself and Steve wrote:
> 
> >> Notice that '+=' creates uses the same object when the object is a
> >> list, but creates a new object. This raises the question: Why and how
> >> does Python behave in this way?
> 
> > Lists are mutable and can be modified in place. Tuples are immutable and
> > cannot be.
> 
> This correctly answers why this happens.
> 
> Steve: I wanted James to think about this question. He learns more
> that way. (I already knew the answer.)

How do you know James doesn't already know the answer too?

If you meant this as a lesson for James, you should have said so. You 
shouldn't have claimed to have been surprised by it:

    "Finally, here's something that surprised me a little bit"


> James: Combining tuple assignment with increment assignment in a
> single statement will increase the cognitive burden on both writer and
> reader of the line of code.

Each additional line we read has to be read as a separate 
operation. Moving things into a single operation can reduce the 
cognitive load, at least sometimes.

Reducing the number of lines

    x += 1
    y += 2
    z += 3

down to one:

    x, y, z += 1, 2, 3  # Hypothetical syntax

could also *decrease* the cognitive burden on the writer or reader if x, 
y, z form a logically connected group. Each additional line of 
code has its own cognitive load just by being an extra line to 
process.

For a small number of simple targets, our brains can chunk the 
assignments into one conceptual operation:

    "assign x, y, z"

instead of three:

    "assign x; then assign y; also assign z"

Hence a reduced cognitive load on both reader and writer.

I see no reason why this chunking can't also apply to augmented 
assignments:

    "increment x, y, z"


but I do worry if it would only chunk effectively if the increment is 
the same:

    x, y, z += 1  # increment each of x, y, z by 1

but not if we have to specify each increment separately:

    x, y, z += 1, 1, 1

I don't have any proof of this concern.



[...]
> But I think there's a code-smell here. Better, I think, is to
> introduce a type that supports augmented assignment. For example
> 
> > vec = Vector(a, b)
> > inc = Vector(c, d)
> > vec += inc

I would like to see Python increase its support for vectorized 
operations. Some years ago I tried adding vectorized support to the 
statistics module as an experiment, but I found that the performance hit 
was horrible, so I abandoned the experiment.

YMMV.

Julia includes syntax to automatically vectorize any operator or 
function:

https://docs.julialang.org/en/v0.6.2/manual/functions/#man-vectorized-1

but that's moving away from the topic on hand.

(Any responses to my vectorization comment, please start a new thread or 
at least change the subject line.)

Back to the original topic...

My gut feeling is that this suggested syntax would work well if there 
was a single value on the right hand side, so that:

    spam, eggs, cheese += foo

is approximately equivalent to:

    # evaluate RHS only once
    _tmp = foo
    spam += _tmp
    eggs += _tmp
    cheese += _tmp

but not so well if we add sequence unpacking on the RHS:

    spam, eggs, cheese += foo, bar, baz


Without adding new syntax, I think we can only pick one set of 
semantics, not both: either a single RHS value, or multiple values.

My intuition is that the first version (a single value on the RHS) is 
not only more useful, but also more readable, since it allows the reader 
to chunk the operation to "increment these three targets" while the 
second doesn't.

That also leaves the door open in the future to adding a vectorized 
version of augmented assignment, if and when we add syntax for 
vectorizing operations a la Julia.

So... a tentative +1 to allowing:

    spam, eggs += foo

and an even more tentative -0 to:

    spam, eggs += foo, bar



-- 
Steve


More information about the Python-ideas mailing list