最初の要素のリストと「テール」を単一のコマンドでアンパックする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]
最初の要素のリストと「テール」を単一のコマンドでアンパックする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()
必要な場合は、オプションの2番目の引数にデフォルト値を指定します。これnext(it, None)
によりNone
、head要素がない場合に表示されます。
当然、リストで作業している場合、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、ラムダを使用
>>> 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]