Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The ,= operator

While looking at some Python code I noticed usage of what looked like ,= operator:

a ,= b

After experimentation and very close inspection of assignment statements syntax, I came to realize it's actually "tuple unpacking" with the tuple a, of length 1 at the left side and the collection b at the right. So in a simple case, it's like the following, but will also work for any iterables/generators:

assert len(b)
a = b[0]

I'm curious if this trick has a name and is there any less obscure technique that achieves the same result?

like image 883
Ilia Barahovsky Avatar asked Jun 13 '26 19:06

Ilia Barahovsky


2 Answers

There is no such operator, it is a normal run of the mill assignment statement with a target list. Most people would use different spacing, a, = b.

You are looking at tuple assignment (also called unpacking), and there can be more than one element on the left. Remember that it is the comma that makes an expression evaluate to a tuple, not the parentheses. The one-target form has no more specific name.

The left-hand side is a tuple with one element, a,. The right-hand side is then unpacked and must contain exactly one element which is then stored in a. If there are more targets on the left, the right-hand side must have a matching number of elements:

>>> 1,  # a tuple with one element
(1,)
>>> a, = 1,  # assigning one value to the left-hand targets.
>>> a
1
>>> a, b = 1,  # not enough elements
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack
>>> a, b = 1, 2, 3  # the syntax requires an exact match, 3 is too many
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> a, b = 1, 2   # two values assigned
>>> a
1
>>> b
2

Assigning to target lists is a normal and widely used feature of the assignment operator, even if not everyone realises this can be used with a one-element tuple as the target.

The technique is in common use when handling an API that'll always produce a tuple or a list, but where you expect just one value. A canonical example is a database API:

cursor.execute('SELECT id FROM TABLE WHERE condition LIMIT 1')
result_id, = cursor.fetchone()

Each row a database query result is always going to be a sequence, even if you only selected one column.

There is no 'less obscure' form of the technique, no. Once you know of it, you don't need any other technique, nor is it obscure any longer!

like image 176
Martijn Pieters Avatar answered Jun 17 '26 21:06

Martijn Pieters


The statement;

a, = b
  • assumes b is iterable
  • take first value from b and assigns it to a (near to a = b[0])
  • asserts that b has no more values (i.e. len(b) == 1)

In that sense it is not the same as a = b[0]. The latter would work with b = ['a', 'b'], while the first will raise a ValueError: too many values to unpack. On the other side:

l = [x]
it = iter(l)
a, = it    #fine when a=it[0] raises TypeError: 'listiterator' object has no attribute '__getitem__'

TL/DR: if b is a list or a tuple with one single element, both a, = b and a = b[0] behave the same, but in other cases the may behave differently

like image 24
Serge Ballesta Avatar answered Jun 17 '26 19:06

Serge Ballesta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!