是否有一种 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]
在 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:]
>>> 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]
在@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]