Почему в списке допускаются конечные запятые?


135

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

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

Это имеет смысл, когда это кортеж, поскольку ('a')и ('a',)- это две разные вещи, но в списках?



7
Завершающая запятая также разрешена в списках на C, C ++, Java, JavaScript и т. Д.
— Наюки

Ответы:


223

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

Изменение:

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

чтобы:

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

включает в себя только однострочное изменение в diff:

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

Это превосходит более запутанный многострочный diff, когда конечная запятая была опущена:

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

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

Это также снижает риск этого:

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

и запускает неявную конкатенацию строкового литерала , производя s = ['manny', 'mo', 'jackroger']вместо предполагаемого результата.


6
В этом есть (самый) смысл, но я был бы очень удивлен, если бы синтаксический анализатор языка был разработан для упрощения различий.
— Бурхан Халид,

94
@BurhanKhalid: Разработчики языков - программисты, и программисты делают много вещей, чтобы облегчить себе жизнь.
— Greg Hewgill

10
@Burhan Если вы не верите этому объяснению, как насчет того, что так проще определить грамматику? ;) Сравнить List = "[" {Item ","} "]".vs.List = "[" ({Item","}Item|)"]".
— Voo

23
Это также упрощает автогенерацию кода для других программ - гораздо проще просто распечатать "\"item\","для каждого элемента, чем печатать "\"item\""для каждого элемента, за которым следуют ","все элементы, кроме последнего.
— Адам Розенфилд

9
@Voo Я тоже думал то же самое, но последняя грамматика все равно должна быть определена, потому что это все еще действующий список Python.
— Александр Сурафель

34

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


30

Это помогает устранить определенный вид ошибки. Иногда проще писать списки в несколько строк. Но при более позднем обслуживании вы можете захотеть переставить элементы.

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

# Now you want to rearrange

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

# Now you have an error

Но если вы разрешите запятые в конце и используете их, вы можете легко изменить порядок строк, не вызывая ошибки.


1
Это удобно, но этого можно избежать, поставив запятую заранее. Я делаю это все время, когда пишу SQL,
— Бурхан Халид

38
Даже если вы добавите запятую к каждому элементу, вам все равно придется опускать запятую в первом элементе.
— Greg Hewgill

Линтер должен уметь это ловить, не так ли?
— viki.omega9 09

6

Кортеж отличается тем, что ('a')раскрывается с использованием неявного продолжения и ()s в качестве оператора приоритета, тогда как ('a',)относится к кортежу длиной 1.

Ваш исходный пример был бы tuple('a')


('a'),это строка; но я хотел сказать, что конечные запятые в кортежах имеют значение, но в списках они не кажутся, пока Python принимает их.
— Burhan Khalid

1
В обоих случаях они молча отбрасываются, просто в кортеже необходимо отличать его от строки в скобках.
— richo

tuple('a')это, наверное, плохой пример, потому что в целом tuple(x)и (x,)это не одно и то же. tuple('ab') != ('ab',), tuple('a') == ('a',)только потому, что 'a'это строка длины 1.
— Чепнер

Из REPL: >>> ("a",) == ("a") Ложь >>> ("ab",) == ("ab") Ложь >>> ("ab", "bc",) == ("ab", "bc") Истина
— Серафья

1

Основная причина - сделать diff менее сложным. Например, у вас есть список:

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

и вы хотите добавить к нему еще один элемент. Тогда вы в конечном итоге сделаете это:

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

таким образом, diff покажет, что две строки были изменены, сначала добавив ',' в строке с 'c' и добавив 'd' в последней строке.

Итак, python допускает завершение ',' в последнем элементе списка, чтобы предотвратить дополнительные различия, которые могут вызвать путаницу.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.