Dlaczego końcowe przecinki są dozwolone na liście?

141

Jestem ciekaw, dlaczego w Pythonie końcowy przecinek na liście jest prawidłową składnią i wydaje się, że Python po prostu go ignoruje:

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

To ma sens, gdy jest to krotka od czasu ('a')i ('a',)są dwie różne rzeczy, ale na listach?

Burhan Khalid
źródło
stackoverflow.com/questions/7992559/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
7
Końcowy przecinek jest również dozwolony w listach w C, C ++, Javie, JavaScript itp.
Nayuki

Odpowiedzi:

233

Głównymi zaletami są to, że ułatwia edycję list wielowierszowych i zmniejsza bałagan w różnicach.

Wymiana pieniędzy:

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

do:

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

obejmuje tylko jedną linię zmiany różnicy:

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

To pokonuje bardziej mylące różnice wieloliniowe, gdy pominięto końcowy przecinek:

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

Ta ostatnia różnica utrudnia dostrzeżenie, że tylko jedna linia została dodana, a druga nie zmieniła zawartości.

Zmniejsza również ryzyko zrobienia tego:

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

i wyzwalanie niejawnej konkatenacji literału ciągu , generując s = ['manny', 'mo', 'jackroger']zamiast zamierzonego wyniku.

Raymond Hettinger
źródło
6
Ma to (najbardziej) sens, ale byłbym naprawdę zaskoczony, gdyby parser języka został zaprojektowany tak, aby ułatwić różnicowanie.
Burhan Khalid
96
@BurhanKhalid: Projektanci języków są programistami, a programiści robią wiele rzeczy, aby ułatwić im życie.
Greg Hewgill,
10
@Burhan Jeśli nie wierzysz w to wyjaśnienie, co powiesz na to, że łatwiej będzie zdefiniować gramatykę w ten sposób? ;) Porównaj List = "[" {Item ","} "]".zList = "[" ({Item","}Item|)"]".
Voo,
23
Ułatwia to również innym programom automatyczne generowanie kodu - o wiele łatwiej jest po prostu wydrukować "\"item\","dla każdego elementu niż wydrukować "\"item\""dla każdego elementu, a następnie ","dla wszystkich elementów oprócz ostatniego.
Adam Rosenfield,
9
@Voo Też myślałem tak samo, ale ta ostatnia gramatyka i tak musi zostać zdefiniowana, ponieważ nadal jest to poprawna lista Pythona.
Alexander Suraphel
35

Jest to powszechna konwencja składniowa zezwalająca na końcowe przecinki w tablicy, języki takie jak C i Java pozwalają na to, a Python wydaje się przyjąć tę konwencję dla swojej struktury danych list. Jest to szczególnie przydatne podczas generowania kodu do zapełniania listy: wystarczy wygenerować sekwencję elementów i przecinków, nie ma potrzeby traktowania ostatniego jako specjalnego przypadku, który nie powinien mieć przecinka na końcu.

Óscar López
źródło
31

Pomaga wyeliminować pewien rodzaj błędu. Czasami łatwiej jest pisać listy w wielu wierszach. Ale w późniejszej konserwacji możesz chcieć zmienić rozmieszczenie elementów.

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

# Now you want to rearrange

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

# Now you have an error

Ale jeśli zezwolisz na końcowe przecinki i użyjesz ich, możesz łatwo zmienić kolejność wierszy bez wprowadzania błędu.

Keith
źródło
1
To fajne, ale możesz tego uniknąć, oczekując na przecinek. Robię to cały czas, pisząc SQL
Burhan Khalid,
39
Nawet jeśli dodasz przecinek do każdego elementu, nadal musisz pominąć przecinek na pierwszym.
Greg Hewgill,
Liniowiec powinien to złapać, prawda?
viki.omega9
6

Krotka jest inna, ponieważ ('a')jest rozwijana przy użyciu niejawnej kontynuacji i ()jako operatora prekendencji, podczas gdy ('a',)odwołuje się do krotki o długości 1.

Twój oryginalny przykład byłby tuple('a')

richo
źródło
('a'),jest ciągiem; ale chodziło mi o to, że końcowe przecinki w krotkach są znaczące, ale na listach nie wydają się być jeszcze Python je akceptuje.
Burhan Khalid
1
Są po cichu odrzucane w obu przypadkach, po prostu w krotce trzeba ją odróżnić od łańcucha w nawiasie.
richo
tuple('a')to chyba zły przykład, bo w ogóle tuple(x)i (x,)to nie to samo. tuple('ab') != ('ab',). tuple('a') == ('a',)tylko dlatego, że 'a'jest to ciąg o długości 1.
chepner
Z REPL: >>> ("a",) == ("a") False >>> ("ab",) == ("ab") False >>> ("ab", "bc",) == ("ab", "bc") True
Seraphya
1

Głównym powodem jest uczynienie diff mniej skomplikowanym. Na przykład masz listę:

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

i chcesz dodać do niego kolejny element. Wtedy skończysz tak:

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

w ten sposób diff pokaże, że dwie linie zostały zmienione, najpierw dodając ',' w linii z 'c' i dodając 'd' w ostatniej linii.

Tak więc python pozwala na kończące się znakiem „” w ostatnim elemencie listy, aby zapobiec dodatkowemu różnicowaniu, które mogłoby spowodować zamieszanie.

Nitish Chauhan
źródło