1つのコマンドで最初の要素のリストと「テール」をアンパックする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]
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()
はオプションの2番目の引数にデフォルト値を取ります。したがって、next(it, None)
は、head要素がない場合に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
>>> 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]