Каково правило синтаксиса для использования запятых в определениях кортежей?

120

В случае одноэлементного кортежа конечная запятая обязательна.

a = ('foo',)

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

a = ('foo1', 'foo2')
b = ('foo1', 'foo2',)
Стан
источник
Вот правило синтаксиса: docs.python.org/reference/expressions.html#expression-lists
Кирилл

Ответы:

73

Во всех случаях, кроме пустого кортежа, важна запятая. Скобки требуются только тогда, когда они необходимы по другим синтаксическим причинам: чтобы отличить кортеж от набора аргументов функции, приоритета оператора или разрешения разрывов строк.

Завершающая запятая для кортежей, списков или аргументов функций - хороший стиль, особенно когда у вас есть длинная инициализация, которая разбита на несколько строк. Если вы всегда включаете конечную запятую, вы не будете добавлять еще одну строку в конец, ожидая добавления еще одного элемента, а вместо этого просто создадите допустимое выражение:

a = [
   "a",
   "b"
   "c"
]

Предполагая, что это началось как список из двух элементов, который позже был расширен, он пошел не так, возможно, не сразу очевидным образом. Всегда включайте запятую в конце, и вы избежите этой ловушки.

Дункан
источник
4
По причинам, указанным выше, может быть полезно оставить запятую. С другой стороны, принятие этой привычки может вызвать головную боль, если вы также имеете дело с JavaScript или JSON в другом месте своего приложения, поскольку некоторым браузерам это не нравится.
Cito
7
Да, но вы никогда не должны создавать JSON вручную, так что это не имеет значения, а для Javascript всегда используйте jslint или эквивалент, чтобы отловить такого рода ошибку, прежде чем она попадет в браузер.
Дункан
101

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

(1)  # the number 1 (the parentheses are wrapping the expression `1`)
(1,) # a 1-tuple holding a number 1

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

например,

someBigTuple = (
                   0,
                   1,
                   2,
                   3,
                   4,
                   5,
                   6,
                   7,
                   8,
                   9,
                   10,
                   #...
                   10000000000,
               )

Обратите внимание, что это относится и к другим коллекциям (например, спискам и словарям), а не только к кортежам.

Джефф Меркадо
источник
5
+1 за указание на то, что это справедливо и для других вещей, кроме кортежей. Это ооочень полезно для того, чтобы иметь по одному key: value,на строку и не заботиться о запятых при добавлении нового материала.
Joël
46

Еще одно преимущество конечных запятых в том, что они делают различия более красивыми. Если вы начали с

a = [
    1,
    2,
    3
]

и изменил его на

a = [
    1,
    2,
    3,
    4
]

Разница будет выглядеть как

 a = [
     1,
     2,
-    3
+    3,
+    4
 ]

Если вы начали с запятой, например

a = [
    1,
    2,
    3,
]

Тогда разница будет просто

 a = [
     1,
     2,
     3,
+    4,
 ]
asmeurer
источник
На самом деле это скорее комментарий, чем ответ на исходный вопрос, но мне очень нравится добавленный аргумент в пользу конечных запятых.
Безумный физик
13

Это необязательно: см. Вики Python .

Резюме: одноэлементным кортежам нужна конечная запятая , но это необязательно для многоэлементных кортежей.

Дэйв Эверитт
источник
7

Также рассмотрите ситуацию, в которой вы хотите:

>>> (('x','y'))*4                         # same as ('x','y')*4
('x', 'y', 'x', 'y', 'x', 'y', 'x', 'y')
#Expected = (('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))

Таким образом, в этом случае внешние скобки - это не что иное, как группирующие скобки. Чтобы сделать их кортежем, вам нужно добавить запятую. т.е.

>>> (('x','y'),)*4 
(('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))
MAPY
источник
Не думайте, что этот ответ касается вопроса, а не неправильного использования кортежа . Если мы ожидаем, что повторяющийся элемент будет типом кортежа, мы явно объявляем тип этого модуля как одноэлементный кортеж. То же самое с списке , попробуйте ['x', 'y'] * 4, [ ['x', 'y'] ] * 4, ( ['x', 'y'], ) * 4
Kuo
6

Завершающая запятая требуется только для одноэлементных кортежей. Наличие конечной запятой для больших кортежей - это вопрос стиля и не требуется. Его самым большим преимуществом является чистый diff для файлов с многострочными большими кортежами, которые часто изменяются (например, кортежи конфигурации).

Адам Зальцман
источник
6

Это простой ответ.

a = ("s") - строка

и

a = ("s",) - кортеж с одним элементом.

Python требуется дополнительная запятая в случае одного кортежа элементов, чтобы различать строку и кортеж.

Например, попробуйте это на консоли Python:

a = ("s")

а = а + (1,2,3)

Отслеживание (последний вызов последний):

Файл stdin, строка 1, в модуле

TypeError: невозможно объединить объекты 'str' и 'tuple'

раджни кант
источник
4

Еще одна причина, по которой это существует, заключается в том, что это упрощает создание кода и __repr__написание функций. Например, если у вас есть объект, подобный построенному obj(arg1, arg2, ..., argn), вы можете просто написать obj.__repr__как

def __repr__(self):
    l = ['obj(']
    for arg in obj.args: # Suppose obj.args == (arg1, arg2, ..., argn)
        l.append(repr(arg))
        l.append(', ')
    l.append(')')
    return ''.join(l)

Если конечная запятая не разрешена, последний аргумент должен быть особенным. Фактически, вы могли бы написать это в одну строку, используя понимание списка (я написал это дольше, чтобы облегчить чтение). Это было бы не так просто, если бы последний семестр был особенным.

asmeurer
источник
2
Не было бы необходимости использовать последний аргумент в особых случаях, можно было бы просто использовать join в том случае: def __repr__(self): 'obj(' + ', '.join([repr(arg) for arg in obj.args]) + ')'.
Suzanne Dupéron
Это также помогает при генерации кода даже из инструментов, написанных не на Python и не имеющих хороших функций, таких как join.
asmeurer
2

PEP 8 - Руководство по стилю для кода Python - Когда использовать конечные запятые

Завершающие запятые обычно являются необязательными, за исключением того, что они являются обязательными при создании кортежа из одного элемента (а в Python 2 они имеют семантику для оператора печати). Для наглядности рекомендуется заключить последнее в (технически избыточные) круглые скобки.

Да:

FILES = ('setup.cfg',)

Хорошо, но сбивает с толку:

FILES = 'setup.cfg',

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

Да:

FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )

Нет:

FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
Быстрый матч
источник
-5

Стиль кодирования - ваш вкус. Если вы думаете, что стандарт кодирования имеет значение, существует PEP-8. который поможет вам.

Что вы думаете о результате следующего выражения?

x = (3)
x = (3+2)
x = 2*(3+2)

Ага, x - это просто число.

Melug
источник
1
это плохой способ объяснить вашу мысль. Явное лучше, чем неявное.
Гильерме Давид да Коста