Семантика множественного присваивания - PullRequest
65 голосов
/ 03 марта 2011

В Python можно сделать:

a, b   = 1, 2
(a, b) = 1, 2
[a, b] = 1, 2

Я проверил сгенерированный байт-код, используя dis, и они идентичны.
Так зачем вообще это разрешать?Мне когда-нибудь понадобится один из них вместо других?

Ответы [ 5 ]

73 голосов
/ 03 марта 2011

Один из случаев, когда вам нужно включить больше структуры в левой части задания, - это когда вы просите, чтобы Python распаковал немного более сложную последовательность.Например:

# Works
>>> a, (b, c) = [1, [2, 3]]

# Does not work
>>> a, b, c = [1, [2, 3]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack

Это оказалось полезным для меня в прошлом, например, при использовании перечисления для итерации последовательности из 2-х кортежей.Что-то вроде:

>>> d = { 'a': 'x', 'b': 'y', 'c': 'z' }
>>> for i, (key, value) in enumerate(d.iteritems()):
...     print (i, key, value)
(0, 'a', 'x')
(1, 'c', 'z')
(2, 'b', 'y')
13 голосов
/ 03 марта 2011

Кортежи Python часто можно написать с круглыми скобками или без них:

a = 1, 2, 3

эквивалентно

a = (1, 2, 3)

В некоторых случаях вам нужны скобки для разрешения неоднозначностей, например, если вы хотите передать кортеж (1, 2) в функцию f, вам нужно будет написать f((1, 2)). Поскольку скобки иногда необходимы, они всегда разрешены для согласованности, так же, как вы всегда можете написать (a + b) вместо a + b.

Если вы хотите распаковать вложенную последовательность, вам также нужны скобки:

a, (b, c) = 1, (2, 3)

Похоже, нет оснований также разрешать использование квадратных скобок, и люди редко делают это.

2 голосов
/ 05 января 2018

При распаковке итерируемого одноэлементного списка синтаксис выглядит красивее:

a,=f()    # comma looks out of place
(a,)=f()  # still odd
[a]=f()   # looks like every other list
2 голосов
/ 03 марта 2011

Они также одинаковы, потому что назначение происходит справа налево и справа, у вас есть один тип, который представляет собой последовательность из двух элементов. Когда выполняется вызов присваивания, последовательность распаковывается и ищет соответствующие элементы для соответствия и присваивается этим значениям. Да, в этом случае все в порядке, если последовательность распакована в соответствующие элементы.

0 голосов
/ 29 июня 2017

Открытая скобка позволяет выполнять многострочное назначение. Например, при чтении строки из csv.reader() это делает код более читабельным (если менее эффективным) для загрузки списка в именованные переменные с помощью одного присваивания.

Начиная с круглых скобок, избегайте длинных или \ экранированных строк.

(a, b, c) = [1, 2, 3]

(представьте себе все больше и больше имен переменных)

...