Python 头尾排成一行

Python 头尾排成一行,python,list,tail,head,Python,List,Tail,Head,是否有一种pythonic方法可以在单个命令中解压第一个元素中的列表和“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] 在Python3.x下,您可以很好地做到这一点: >>> head, *tail = [1

是否有一种pythonic方法可以在单个命令中解压第一个元素中的列表和“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]

在Python3.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]
x中的一个新特性是在解包时使用
*
操作符,表示任何额外的值。如中所述。这还具有处理任何iterable而不仅仅是序列的优点

它也非常可读

如PEP中所述,如果您想在2.x下执行等效操作(而不可能创建临时列表),则必须执行以下操作:

it = iter(iterable)
head, tail = next(it), list(it)
如注释中所述,这还提供了一个机会,可以获取
头的默认值,而不是抛出异常。如果您想要这种行为,则会使用带有默认值的可选第二个参数,因此如果没有head元素,
next(it,None)
将为您提供
None

当然,如果您正在处理列表,没有3.x语法的最简单方法是:

head, tail = seq[0], seq[1:]
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
操作的O(1)复杂性,您应该使用
deque

以下方式:

from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l
当您必须遍历列表中的所有元素时,它非常有用。例如,在naive合并中,合并排序中有两个分区

基于,下面是一种在Python2中获得没有中间变量的单行等价物的方法

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]

对不起,我不恰当地使用了tail这个词。我的意思是我在示例中所说的,那是没有第一个的列表element@NikolayFominyh它们都是相同的——它们都接受head元素并构造一个包含tail元素的新列表。复杂性没有差别。另一个类可以实现
\uuuu getitem\uuuuuu
/
\uuuu setitem\uuuuuu
来惰性地执行尾部操作,但内置列表没有。在一个包含800个元素的列表中,我有2.8s的头部,*tail=seq解决方案,只有1.8s的头部,tail=seq[0],seq[1:]解决方案。列表的切片速度更快。@CMCDRANGKAI不,Python的主列表类是数组列表。这可能是O(n),因为它涉及到将尾部复制到一个新列表(头部有一个O(1)get)。这种好的语法是移动到
python 3.x
的另一个原因。请记住,在python中列表不是作为单链接列表实现的,因此此操作成本很高(例如:需要复制整个列表)。根据您想要实现的目标,这可能是问题,也可能不是问题。我刚刚提到的是,因为这种类型的列表解构经常出现在函数式语言中,实际上这是一种非常便宜的操作。我说错了吗?@аааааааааааааа107。但是,如果您想多次访问第一个元素,那么
head,tail=l.popleft(),l
是~O(1)
head,tail=seq[0],seq[1://code>是O(n)。看起来你可以做
head=l.popleft()
,而
tail
只是
l
的别名。如果
l
改变
tail
也改变了。你到底为什么要这样做而不仅仅是
head,tail=lst[0],lst[1:
?如果OP的意思是使用文字,那么他可以手动拆分头和尾
head,tail=1,[1,2,3,5,8,13,21,34,55]
(1)OP的问题是是否可以在一行中执行此操作(所以在前一行中没有
lst=…
)。(2) 做
head,tail=lst[0],lst[1://code>会让代码产生副作用(考虑
head,tail=get_list()[0],get_list()[1://code>),这与Op的形式
head,tail=**应用于**[1,1,2,3,5,8,13,21,34,55]的一些魔法不同,我承认,这是一种很糟糕的混淆方式来获取头部/尾部。但我认为这是Python2针对Op的具体问题的最佳答案。
h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]