単一のコマンドで最初の要素のリストと「テール」を解凍する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-ExtendedIterableUnpackingで説明されています。これには、シーケンスだけでなく、反復可能なものを処理できるという利点もあります。
それも本当に読みやすいです。
PEPで説明されているように、2.xで同等の処理を(一時的なリストを作成せずに)実行する場合は、次のようにする必要があります。
it = iter(iterable)
head, tail = next(it), list(it)
head
コメントに記載されているように、これは例外をスローするのではなく、のデフォルト値を取得する機会も提供します。この動作がnext()
必要な場合は、デフォルト値を持つオプションの2番目の引数を取るので、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、ラムダを使用
>>> 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のPython2ソリューションに基づいて構築された以下は、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]