Голова и хвост в одну линию

Есть ли питонный способ распаковать список в первом элементе и "хвост" в одной команде?

Например:

>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

Ответ 1

В Python 3.x вы можете сделать это красиво:

>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

Новая функция в 3.x заключается в использовании оператора * при распаковке для обозначения любых дополнительных значений. Это описано в PEP 3132 - Расширенная итеративная распаковка. Это также имеет преимущество работы с любыми повторяемыми, а не только с последовательностями.

Это также действительно читабельно.

Как описано в PEP, если вы хотите сделать эквивалент в 2.x (без потенциального создания временного списка), вы должны сделать это:

it = iter(iterable)
head, tail = next(it), list(it)

Естественно, если вы работаете со списком, самый простой способ без синтаксиса 3.x:

head, tail = seq[0], seq[1:]

Ответ 2

>>> mylist = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head, tail = mylist[0], mylist[1:]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

Ответ 3

Для O (1) сложности операции head,tail вы должны использовать deque.

Следующим образом:

from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l

Это полезно, когда вы должны выполнять итерацию по всем элементам списка. Например, в наивном объединении 2 разделов в сортировке слияния.

Ответ 4

Python 2, используя lambda

>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

Ответ 5

Основываясь на решении Python 2 от @GarethLatty, ниже представлен способ получить однострочный эквивалент без промежуточных переменных в Python 2.

t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]

Если вам нужно, чтобы он был защищен от исключений (т.е. поддерживает пустой список), добавьте:

t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]

Если вы хотите сделать это без точки с запятой, используйте:

h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]