Perché le virgole finali sono consentite in un elenco?


135

Sono curioso di sapere perché in Python una virgola finale in un elenco sia una sintassi valida e sembra che Python semplicemente la ignori:

>>> ['a','b',]
['a', 'b']

Ha senso quando è una tupla da allora ('a')e ci ('a',)sono due cose diverse, ma nelle liste?



7
Una virgola finale è consentita anche negli elenchi in C, C ++, Java, JavaScript, ecc.
Nayuki,

Risposte:


223

I principali vantaggi sono che semplifica la modifica degli elenchi multilinea e riduce il disordine nei diff.

Mutevole:

s = ['manny',
     'mo',
     'jack',
]

per:

s = ['manny',
     'mo',
     'jack',
     'roger',
]

comporta solo una modifica di una riga nel diff:

  s = ['manny',
       'mo',
       'jack',
+      'roger',
  ]

Questo batte il diff di più righe più confuso quando la virgola finale è stata omessa:

  s = ['manny',
       'mo',
-      'jack'
+      'jack',
+      'roger'
  ]

Quest'ultima differenza rende più difficile vedere che è stata aggiunta solo una riga e che l'altra riga non ha modificato il contenuto.

Riduce anche il rischio di farlo:

s = ['manny',
     'mo',
     'jack'
     'roger'  # Added this line, but forgot to add a comma on the previous line
]

e innescando la concatenazione letterale di stringa implicita , producendo s = ['manny', 'mo', 'jackroger']invece del risultato desiderato.


6
Questo ha il senso (più) sensato, ma sarei davvero sorpreso se il parser del linguaggio fosse progettato per rendere le differenze più facili.
Burhan Khalid,

94
@BurhanKhalid: i progettisti linguistici sono programmatori e programmatori fanno molte cose per rendere la loro vita più semplice.
Greg Hewgill,

10
@Burhan Se non credi a questa spiegazione, che ne dici se è anche più semplice definire la grammatica in quel modo? ;) Confronta List = "[" {Item ","} "]".vs.List = "[" ({Item","}Item|)"]".
Voo

23
Ciò semplifica anche la generazione automatica del codice da parte di altri programmi: è molto più semplice stampare "\"item\","per ciascun elemento piuttosto che stampare "\"item\""per ciascun elemento seguito da ","tutti tranne l'ultimo.
Adam Rosenfield,

9
@Voo Anche io ho pensato lo stesso, ma quest'ultima grammatica deve essere definita comunque perché è ancora un elenco Python valido.
Alexander Suraphel,

34

È una convenzione sintattica comune per consentire le virgole finali in un array, linguaggi come C e Java lo consentono e Python sembra aver adottato questa convenzione per la sua struttura di dati di elenco. È particolarmente utile quando si genera codice per popolare un elenco: basta generare una sequenza di elementi e virgole, non è necessario considerare l'ultimo come un caso speciale che non dovrebbe avere una virgola alla fine.


30

Aiuta ad eliminare un certo tipo di bug. A volte è più chiaro scrivere elenchi su più righe. Ma in seguito, potresti voler riorganizzare gli articoli.

l1 = [
        1,
        2,
        3,
        4,
        5
]

# Now you want to rearrange

l1 = [
        1,
        2,
        3,
        5
        4,
]

# Now you have an error

Ma se consenti le virgole finali e le usi, puoi facilmente riorganizzare le linee senza introdurre un errore.


1
Questo è pulito, ma puoi evitarlo anticipando la virgola. Lo faccio sempre quando scrivo SQL
Burhan Khalid il

38
Anche se anteponi la virgola a ciascun elemento, devi comunque omettere la virgola sul primo.
Greg Hewgill,

Una linter dovrebbe essere in grado di catturare questo, no?
viki.omega9,

6

Una tupla è diversa perché ('a')viene espansa usando la continuazione implicita ()es come operatore di precendenza, mentre si ('a',)riferisce a una tupla di lunghezza 1.

Il tuo esempio originale sarebbe stato tuple('a')


('a'),è una stringa; ma il mio punto era che le virgole finali nelle tuple sono significative, ma nelle liste non sembrano essere ancora Python le accetta.
Burhan Khalid,

1
Vengono scartati silenziosamente in entrambi i casi, è solo che in una tupla è necessario differenziarlo da una stringa tra parentesi.
Richo,

tuple('a')è probabilmente un cattivo esempio, perché in generale tuple(x)e (x,)non sono la stessa cosa. tuple('ab') != ('ab',). tuple('a') == ('a',)solo perché 'a'è una stringa di lunghezza 1.
chepner

Dal REPL: >>> ("a",) == ("a") False >>> ("ab",) == ("ab") False >>> ("ab", "bc",) == ("ab", "bc") True
Seraphya,

1

Il motivo principale è rendere le differenze meno complicate. Ad esempio hai un elenco:

list = [
    'a',
    'b',
    'c'
]

e vuoi aggiungere un altro elemento ad esso. Quindi finirai per fare questo:

list = [
    'a',
    'b',
    'c',
    'd'
]

pertanto, diff mostrerà che sono state modificate due righe, aggiungendo prima ',' in linea con 'c' e aggiungendo 'd' all'ultima riga.

Quindi, python consente di trascinare ',' nell'ultimo elemento della lista, per prevenire diff diff che possono causare confusione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.