Есть ли питонный способ распаковать список в первом элементе и "хвост" в одной команде?
Например:
>> 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]
Есть ли питонный способ распаковать список в первом элементе и "хвост" в одной команде?
Например:
>> 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]
В 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:]
>>> 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]
Для 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 разделов в сортировке слияния.
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]
Основываясь на решении 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]