有没有一种Python方式可以在单个命令中解压缩第一个元素和“ tail”中的列表?
例如:
>> 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方式可以在单个命令中解压缩第一个元素和“ tail”中的列表?
例如:
>> 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]
Answers:
在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)
如评论中所述,这也提供了获得默认值head
而不是引发异常的机会。如果您要执行此操作,请next()
使用可选的第二个参数作为默认值,如果没有head元素,next(it, None)
则会给出提示None
。
自然,如果您正在处理列表,则不使用3.x语法的最简单方法是:
head, tail = seq[0], seq[1:]
__getitem__
/ __setitem__
延迟执行尾操作,但是内置列表则不能。
python 3.x
对于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个分区。
head, tail = l.popleft(), l
则为〜O(1)。head, tail = seq[0], seq[1:]
是O(n)。
head = l.popleft()
,tail
并且只是的别名l
。如果l
变化也tail
变化。
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]
head, tail = lst[0], lst[1:]
?如果OP表示要使用文字,那么他可以手动拆分头和尾head, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
lst = ...
在上一行中没有)。(2)这样做head, tail = lst[0], lst[1:]
会使代码易于产生副作用(请考虑head, tail = get_list()[0], get_list()[1:]
),并且与Op的形式不同head, tail = **some_magic applied to** [1, 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]