103

是否有一种 Pythonic 方法可以在单个命令中解压缩第一个元素中的列表和“尾部”?

例如:

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

5 回答 5

219

在 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, tail = next(it), list(it)

如评论中所述,这也提供了获取默认值head而不是引发异常的机会。如果您想要这种行为,请next()使用带有默认值的可选第二个参数,如果没有 head 元素,则next(it, None)会给您。None

自然,如果您正在处理列表,那么不使用 3.x 语法的最简单方法是:

head, tail = seq[0], seq[1:]
于 2012-05-10T10:53:20.737 回答
38
>>> 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]
于 2012-05-10T10:54:29.847 回答
10

但是,对于 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 个分区。

于 2016-10-03T18:21:30.653 回答
3

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]
于 2016-07-13T19:31:08.377 回答
2

在@GarethLatty的Python 2 解决方案的基础上,以下是在 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]
于 2018-07-30T17:18:22.590 回答