2012-05-10 5 views
60

Есть ли пифонический способ распаковать список в первом элементе и «хвост» в одной команде?голова и хвост python в одной строке

Например:

>> 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] 
+7

Помните, что списки не реализованы как односвязные списки в Python, поэтому эта операция является дорогостоящей (как в: весь список необходимо скопировать). В зависимости от того, чего вы хотите достичь, это может быть или не быть проблемой. Я просто упоминаю об этом, потому что этот тип деструктурирования списка часто встречается в функциональных языках, где это действительно очень дешевая операция. –

ответ

126

Под 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 - Extended Iterable Unpacking. Это также имеет преимущество в работе над любыми итерабельными, а не только последовательностями.

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

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

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

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

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

Извините, я использовал термин хвост неспешно. Я имею в виду то, что я говорю в примере, то есть список без первого элемента. –

+0

@ Giacomod'Antonio. Моя ошибка, я не читал достаточно внимательно. То, что вы сказали, является нормальным значением хвоста. На самом деле это делает его еще проще. –

+0

+1 для решений Python 2.x и 3.x – Patrick

31
>>> 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

Python 2, с помощью лямбда-

>>> 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] 
6

Для 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 разделов в сортировке слияния.

+0

Кажется, что deque (list_instance) имеет сложность O (N). Я ошибаюсь? –

+1

@ НикитаКонин, вы правы о строительстве deque. Однако, если вы хотите получить доступ к первому элементу более одного раза, тогда 'head, tail = l.popleft(), l' is ~ O (1). 'head, tail = seq [0], seq [1:]' is O (n). –

Смежные вопросы