Недавно я был удивлен, обнаружив, что оператор "splat" (унарный *) всегда захватывает фрагменты как list
во время распаковки элемента, даже когда распаковываемая последовательность имеет другой тип:
>>> x, *y, z = tuple(range(5))
>>> y
[1, 2, 3] # list, was expecting tuple
Сравните с тем, как это назначение было бы записано без распаковки:
>>> my_tuple = tuple(range(5))
>>> x = my_tuple[0]
>>> y = my_tuple[1:-1]
>>> z = my_tuple[-1]
>>> y
(1, 2, 3)
Это также несовместимо с поведением оператора splat в аргументах функции:
>>> def f(*args):
... return args, type(args)
...
>>> f()
((), <class 'tuple'>)
Для восстановления y
в качестве кортежа после распаковки я теперь должен написать:
>>> x, *y, z = tuple(range(5))
>>> y = tuple(y)
Что все еще намного лучше, чем синтаксис на основе слайсов, но тем не менее страдает от того, что я считаю очень ненужной и неожиданной потерей элегантности , Есть ли способ восстановить y
в виде кортежа вместо списка без обработки после назначения?
Я пытался заставить python интерпретировать y
как кортеж, написав x, *(*y,), z = ...
, но он все равно оказался списком. И конечно глупые вещи вроде x, *tuple(y), z
не работают в python.
В настоящее время я использую Python 3.6.9, но решения / предложения / объяснения, включающие более высокие версии также приветствуются.