The ,= operator

前端 未结 2 1014
梦毁少年i
梦毁少年i 2021-01-21 06:30

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

a ,= b

After experimentation and very close ins

相关标签:
2条回答
  • 2021-01-21 06:51

    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!

    0 讨论(0)
  • 2021-01-21 06:54

    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

    0 讨论(0)
提交回复
热议问题