Is there a reason why python can not perform an in-place add operation when unpacking tuples, and is there a simple way around this?
E.g.
>>> x, y = (5, 0)
>>> x, y += (1, 8)
SyntaxError: illegal expression for augmented assignment
The alternatives are ugly and not very obvious for code maintenance:
>>> x, y = (5, 0)
>>> x, y = map(sum, zip((x, y), (1, 8)))
Answer
The reason Python does not support in-place augmented assignment when unpacking tuples (like x, y += (1, 8)
) is because of how Python handles the assignment and operator overloading in the context of tuple unpacking.
In Python, the +=
operator (augmented assignment) modifies an existing variable in place. However, when you perform tuple unpacking, such as x, y = (5, 0)
, you are effectively assigning values to new variables from a tuple. The augmented assignment operator expects to modify the variables directly, but in the case of tuple unpacking, Python needs to assign multiple variables at once, which causes the conflict with how augmented assignment works.
Why x, y += (1, 8)
doesn't work:
- Tuple unpacking:
x, y = (5, 0)
assigns values tox
andy
. - Augmented assignment:
x, y += (1, 8)
tries to apply+=
to the unpacked tuple, but Python doesn’t support augmented assignments for multiple variables in a tuple directly. It treats the right-hand side of the+=
as a tuple and tries to apply+=
to the whole tuple instead of individual elements.
Workaround with map
and zip
:
Your solution with map(sum, zip((x, y), (1, 8)))
is a valid workaround, where you're combining the values element by element and then applying the sum. This approach is explicit, but I understand it can seem a little unwieldy for simple cases.
A more readable alternative:
Here are some more idiomatic or alternative ways to handle this:
1. Use separate assignments (for clarity and readability):
x, y = (5, 0)
x += 1
y += 8
This is simple, straightforward, and avoids the need for map()
or zip()
. It’s easy to understand, and there’s no ambiguity.
2. Using zip
and map
but with a clearer breakdown:
x, y = (5, 0)
x, y = map(lambda a, b: a + b, (x, y), (1, 8))
This is a slight improvement over the sum
version, as it makes the operation explicit and clear that you're performing addition.
3. Use tuple
unpacking in a more explicit way:
You can unpack and perform the addition explicitly in one line:
x, y = (5, 0)
x, y = (x + 1, y + 8)
This is a direct way to add to each variable and reassign them back without the need for auxiliary functions like map
or zip
.
4. Using a for
loop (if there are more variables):
If you have many variables to unpack and add, you could use a loop to iterate and perform the operation:
x, y = (5, 0)
for var, increment in zip((x, y), (1, 8)):
var += increment
But note, this isn't quite the same as the +=
syntax you'd expect for simple operations, and it still doesn't allow in-place modification like +=
for multiple variables.
Conclusion:
The core issue is that tuple unpacking and augmented assignment don't naturally work together in Python. The simplest, most readable solutions are either separate assignments (x += 1
and y += 8
) or performing the operation directly in the tuple unpacking (x, y = (x + 1, y + 8)
). Using zip
and map
might work for more complex cases, but it's not necessary for simpler operations.