Python augmenting multiple variables inline

11,488

Solution 1

You cannot use an augmented assignment statement on multiple targets, no.

Quoting the augmented assignment documentation:

With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible in-place behavior, the binary operation performed by augmented assignment is the same as the normal binary operations.

Emphasis mine.

In-place augmented assignment is translated from target -= expression to target = target.__isub__(expression) (with corresponding __i...__ hooks for each operator) and translating that operation to multiple targets is not supported.

Under the hood, augmented assignment is a specialisation of the binary operators (+, *, -, etc), not of assignment. Because the implementation is based on those operators and binary operators only ever have two operands, multiple targets were never included in the original implementation proposal.

You'll have to simply apply the assignments separately:

x -= 1
y -= 2

or, if you really, really wanted to get convoluted, use the operator module and zip() to apply operator.isub to the combinations (via itertools.starmap(), then use tuple assignment:

from operator import sub
from itertools import starmap

x, y = starmap(operator.isub, zip((x, y), (1, 2)))

where isub will ensure that the right hook is called allowing for in-place subtraction for mutable types that support it.

or, if you are manipulating types that don't support in-place manipulation, using a generator expression suffices:

x, y = (val - delta for val, delta in zip((x, y), (1, 2)))

Solution 2

This x, y = (1, 2) is sequence assignment. It relies on the right hand side being an iterable object, and the left hand side being composed of the same number of variables as iterating the left hand side provides.

This x, y -= (1, 2) is attempt to call the method __isub__ on the left hand operand(s). The nature of an in-place ("augmented") assignment is that it must take a variable on its left hand side, whose value receives the operator call, and the variable then receives the result of that call. Python does not allow distribution of an in-place assignment over multiple targets.

Share:
11,488

Related videos on Youtube

RabbitInAHole
Author by

RabbitInAHole

Updated on June 04, 2022

Comments

  • RabbitInAHole
    RabbitInAHole almost 2 years

    Why does this work

    >> x, y = (1, 2)
    >> print x, y
    1 2
    

    But augmenting results in syntax errors..

    >> x, y -= (1, 2)
    SyntaxError: illegal expression for augmented assignment
    

    Is there a different way, I was expecting:

    >> x, y -= (1, 2)
    >> print x, y
    0 0
    
    • Arya McCarthy
      Arya McCarthy about 5 years
      Something not covered in the solutions, for people who stumble across this question: You can do the type of math you want with numpy arrays.
    • tcpaiva
      tcpaiva about 2 years
      I know you mentioned augmented assignment, but in this case I would just do x, y = x-1, y-2