Qual é a regra de sintaxe para ter vírgulas finais nas definições de tupla?

119

No caso de uma tupla de elemento único, a vírgula final é necessária.

a = ('foo',)

Que tal uma tupla com vários elementos? Parece que se a vírgula final existe ou não, ambos são válidos. Isso está correto? Ter uma vírgula final é mais fácil para editar, na minha opinião. É um estilo de codificação ruim?

a = ('foo1', 'foo2')
b = ('foo1', 'foo2',)
Stan
fonte
Aqui está a regra de sintaxe: docs.python.org/reference/expressions.html#expression-lists
Kirill

Respostas:

73

Em todos os casos, exceto na tupla vazia, a vírgula é o mais importante. Os parênteses são necessários apenas quando necessários por outras razões sintáticas: para distinguir uma tupla de um conjunto de argumentos de função, precedência de operador ou para permitir quebras de linha.

A vírgula final para tuplas, listas ou argumentos de função é um bom estilo, especialmente quando você tem uma inicialização longa que é dividida em várias linhas. Se você sempre incluir uma vírgula no final, não adicionará outra linha ao final esperando adicionar outro elemento, mas apenas criando uma expressão válida:

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

Assumindo que começou como uma lista de 2 elementos que foi posteriormente estendida, deu errado de uma forma talvez não imediatamente óbvia. Sempre inclua a vírgula final e você evita essa armadilha.

Duncan
fonte
3
Pelas razões expostas acima, deixar a vírgula pode ser vantajoso. Por outro lado, adotar esse hábito pode causar dores de cabeça se você também estiver lidando com JavaScript ou JSON em outro lugar em seu aplicativo, já que alguns navegadores não gostam disso.
Cito
7
Sim, mas você nunca deve construir JSON manualmente, então isso não importa, e para Javascript sempre use jslint ou equivalente para detectar esse tipo de erro antes que ele chegue perto de um navegador.
Duncan
100

É necessário apenas para tuplas de item único para eliminar a ambigüidade de definir uma tupla ou uma expressão entre parênteses.

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

Para mais de um item, não é mais necessário, pois está perfeitamente claro que é uma tupla. No entanto, a vírgula final é permitida para tornar mais fácil defini-los usando várias linhas. Você pode adicionar no final ou reorganizar os itens sem quebrar a sintaxe porque você deixou uma vírgula por acidente.

por exemplo,

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

Observe que isso se aplica a outras coleções (por exemplo, listas e dicionários) também e não apenas a tuplas.

Jeff Mercado
fonte
5
+1 por apontar que isso também é válido para outras coisas além de tuplas. Isso é muuuito útil para ter um key: value,por linha e não cuidar de vírgulas ao adicionar coisas novas.
Joël
46

Outra vantagem das vírgulas finais é que faz com que as diffs pareçam mais bonitas. Se você começou com

a = [
    1,
    2,
    3
]

e mudou para

a = [
    1,
    2,
    3,
    4
]

O diff pareceria

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

Considerando que se você tivesse começado com uma vírgula final, como

a = [
    1,
    2,
    3,
]

Então a diferença seria apenas

 a = [
     1,
     2,
     3,
+    4,
 ]
asmeurer
fonte
Este é realmente mais um comentário do que uma resposta à pergunta original, mas eu realmente gosto do argumento adicionado a favor das vírgulas finais.
Mad Physicist
13

É opcional: consulte o wiki do Python .

Resumo: tuplas de elemento único precisam de uma vírgula final , mas é opcional para tuplas de elementos múltiplos.

Dave Everitt
fonte
8

Além disso, considere a situação em que deseja:

>>> (('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'))

Portanto, neste caso, os parênteses externos nada mais são do que parênteses de agrupamento. Para torná-los tuplas, você precisa adicionar uma vírgula final. ie

>>> (('x','y'),)*4 
(('x', 'y'), ('x', 'y'), ('x', 'y'), ('x', 'y'))
MaPy
fonte
6

A vírgula final é necessária apenas para tuplas de um elemento. Ter uma vírgula final para tuplas maiores é uma questão de estilo e não é obrigatório. Sua maior vantagem é limpar diferenças em arquivos com grandes tuplas de várias linhas que são frequentemente modificadas (por exemplo, tuplas de configuração).

Adam Zalcman
fonte
6

Essa é uma resposta simples.

a = ("s") é uma string

e

a = ("s",) é uma tupla com um elemento.

Python precisa de uma vírgula adicional no caso de uma tupla de elemento para diferenciar entre string e tupla.

Por exemplo, tente isso no console Python:

a = ("s")

a = a + (1,2,3)

Traceback (última chamada mais recente):

Arquivo stdin, linha 1, no módulo

TypeError: não é possível concatenar objetos 'str' e 'tuple'

rajni kant
fonte
4

Outra razão pela qual isso existe é que torna a geração de código e __repr__funções mais fáceis de escrever. Por exemplo, se você tem algum objeto que é construído como obj(arg1, arg2, ..., argn), então você pode simplesmente escrever obj.__repr__como

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)

Se uma vírgula final não fosse permitida, você teria que colocar uma caixa especial no último argumento. Na verdade, você poderia escrever o texto acima em uma linha usando uma compreensão de lista (eu escrevi por mais tempo para torná-lo mais fácil de ler). Não seria tão fácil fazer isso se você tivesse um caso especial no último semestre.

asmeurer
fonte
2
Não haveria necessidade de-caso especial o último argumento, pode-se usar apenas joinnesse caso: def __repr__(self): 'obj(' + ', '.join([repr(arg) for arg in obj.args]) + ')'.
Suzanne Dupéron
Também ajuda na geração de código, mesmo de ferramentas que não são escritas em Python e não têm funções legais como join.
asmeurer
2

PEP 8 - Guia de estilo para código Python - quando usar vírgulas finais

As vírgulas finais são geralmente opcionais, exceto que são obrigatórias ao fazer uma tupla de um elemento (e no Python 2 elas têm semântica para a instrução de impressão). Para maior clareza, é recomendável colocar o último entre parênteses (tecnicamente redundantes).

Sim:

FILES = ('setup.cfg',)

OK, mas confuso:

FILES = 'setup.cfg',

Quando as vírgulas finais são redundantes, geralmente são úteis quando um sistema de controle de versão é usado, quando se espera que uma lista de valores, argumentos ou itens importados seja estendida ao longo do tempo. O padrão é colocar cada valor (etc.) em uma linha sozinho, sempre adicionando uma vírgula final e adicionar o parêntese / colchete / chave na próxima linha. No entanto, não faz sentido ter uma vírgula à direita na mesma linha do delimitador de fechamento (exceto no caso acima de tuplas de singleton).

Sim:

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

Não:

FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
Speedy Match
fonte
-5

O estilo de codificação é o seu gosto. Se você acha que o padrão de codificação é importante, há um PEP-8 que pode orientá-lo.

O que você acha do resultado da seguinte expressão?

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

Sim, x é apenas um número.

Melug
fonte
1
essa é uma maneira pobre de explicar sua linha de pensamento. Explícito é melhor do que implícito.
Guilherme David da Costa