Этот вопрос будет довольно длинным, поэтому я прошу прощения.
В Python мы можем использовать * в следующих трех случаях:
I. При определении функции, которую мы хотим вызвать с произвольным числом аргументов, например, в этом примере :
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
В этом случае избыточные позиционные аргументы собираются в кортеж .
II. Обратный случай - когда аргументы уже находятся в списке или кортеже , и мы хотим распаковать их для вызова функции, требующей отдельные позиционные аргументы, такие как в этом примере :
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
III. Начиная с Python 3, * также используется в контексте расширенной списка или кортежа распаковки, такого как в этом примере для кортежей:
>>> a, *b, c = range(5)
>>> b
[1, 2, 3]
или для списков:
>>> [a, *b, c] = range(5)
>>> b
[1, 2, 3]
В обоих случаях все элементы из повторяемого пакета, которые не были распакованы и не назначены ни одному из обязательных выражений, присваиваются списку .
Так вот вопрос: в случае I дополнительные аргументы собираются в кортеж , тогда как в случае III дополнительные элементы назначаются список . Откуда это несоответствие? Единственное объяснение, которое я смог найти, было в PEP 3132, в котором говорится:
Обсуждались возможные изменения:
[...]
Сделать помеченную цель кортежем вместо списка. Это было бы
в соответствии с * аргументами функции,
но сделать дальнейшую обработку
результат сложнее.
Тем не менее, с педагогической точки зрения это непоследовательность проблематична, особенно учитывая, что если вы хотите обработать результат, вы всегда можете сказать list (b) (предполагая, что b в приведенных выше примерах было кортежем). Я что-то упустил?