これまでのソリューションはリストのみを扱い、ほとんどはリストをコピーしていました。私の経験では、それは不可能な場合が多いです。
また、リスト内で要素を繰り返すことができるという事実を扱いません。
質問のタイトルには「ループ内の前と次の値」と書かれていますが、ここでほとんどの回答をループ内で実行すると、各要素でリスト全体を繰り返し処理して見つけることになります。
だから私は関数を作成しました。モジュールを使用してitertools
、イテラブルを分割およびスライスし、前の要素と次の要素を一緒にしてタプルを生成します。あなたのコードが何をするかは正確ではありませんが、おそらくあなたの問題を解決できるので、一見の価値があります。
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
次に、ループで使用すると、前と次のアイテムが含まれます。
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
結果:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
これは、任意のサイズ リスト (リストをコピーしないため) と、任意のイテラブル (ファイル、セットなど) で動作します。このようにして、シーケンスを反復するだけで、ループ内で前と次のアイテムを使用できるようになります。シーケンス内のアイテムを再度検索する必要はありません。
コードの簡単な説明:
tee
入力シーケンスに対して 3 つの独立した反復子を効率的に作成するために使用されます
chain
2 つのシーケンスを 1 つにリンクします。ここでは、単一要素のシーケンス[None]
を追加するために使用されますprevs
islice
最初の要素を除くすべての要素のシーケンスを作成するために使用され、最後に a をchain
追加するために使用されますNone
some_iterable
次のような
3 つの独立したシーケンスがあります。
prevs
:None, A, B, C, D, E
items
:A, B, C, D, E
nexts
:B, C, D, E, None
- finally
izip
は、3 つのシーケンスをトリプレットの 1 つのシーケンスに変更するために使用されます。
izip
入力シーケンスが使い果たされると停止することに注意してください。そのため、 の最後の要素はprevs
無視されます。これは正しいです。最後の要素がその になるような要素はありませんprev
。から最後の要素を取り除こうとすることもできますprevs
が、izip
の動作により冗長になります
tee
また、 、izip
、islice
およびがモジュールにchain
由来することにも注意してください。itertools
入力シーケンスをその場で (遅延して) 操作するため、効率的になり、いつでも一度にシーケンス全体をメモリに保持する必要がなくなります。
ではpython 3
、インポート中にエラーが表示されますが、代わりに をizip
使用できます。インポートする必要はありません。 ソースで事前定義されていますzip
izip
zip
python 3