ループでループしながら、次または前の要素list
にアクセスする方法はありますか?tuple
for
l = [1, 2, 3]
for item in l:
if item == 2:
get_previous(l, item)
ジェネレータ関数として表現:
def neighborhood(iterable):
iterator = iter(iterable)
prev_item = None
current_item = next(iterator) # throws StopIteration if empty.
for next_item in iterator:
yield (prev_item, current_item, next_item)
prev_item = current_item
current_item = next_item
yield (prev_item, current_item, None)
使用法:
for prev,item,next in neighborhood(l):
print prev, item, next
l = [1, 2, 3]
for i, j in zip(l, l[1:]):
print(i, j)
l = [1, 2, 3]
for i, item in enumerate(l):
if item == 2:
previous = l[i - 1]
print(previous)
出力:
1
探しているアイテムがリストの最初のアイテムである場合、これはラップアラウンドしてリストの最後のアイテムを返します。つまりif item == 1:
、上記のコードの 3 行目を に変更すると、 が出力されます3
。
コンテキストが必要なジェネレーターを扱う場合、以下のユーティリティ関数を使用して、イテレーターにスライディング ウィンドウ ビューを表示することがよくあります。
import collections, itertools
def window(it, winsize, step=1):
"""Sliding window iterator."""
it=iter(it) # Ensure we have an iterator
l=collections.deque(itertools.islice(it, winsize))
while 1: # Continue till StopIteration gets raised.
yield tuple(l)
for i in range(step):
l.append(it.next())
l.popleft()
一度に N 項目のシーケンスのビューを生成し、ステップの場所をシフトします。例えば。
>>> list(window([1,2,3,4,5],3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
次または前の値を持たずに数値を処理する必要がある先読み/背後の状況で使用する場合は、None などの適切な値でシーケンスをパディングすることができます。
l= range(10)
# Print adjacent numbers
for cur, next in window(l + [None] ,2):
if next is None: print "%d is the last number." % cur
else: print "%d is followed by %d" % (cur,next)
私はこれが古いことを知っていますが、なぜ単に使用しないのenumerate
ですか?
l = ['adam', 'rick', 'morty', 'adam', 'billy', 'bob', 'wally', 'bob', 'jerry']
for i, item in enumerate(l):
if i == 0:
previous_item = None
else:
previous_item = l[i - 1]
if i == len(l) - 1:
next_item = None
else:
next_item = l[i + 1]
print('Previous Item:', previous_item)
print('Item:', item)
print('Next Item:', next_item)
print('')
pass
これを実行すると、前のアイテムと次のアイテムが取得され、リスト内のアイテムの繰り返しは気にされないことがわかります。
Tempita プロジェクトのルーパー ユーティリティをチェックしてください。前、次、最初、最後などのプロパティを提供するループアイテムのラッパーオブジェクトを提供します。
ルーパー クラスのソース コードを見てください。非常に単純です。このようなループ ヘルパーは他にもありますが、今のところ他に思い出せません。
例:
> easy_install Tempita
> python
>>> from tempita import looper
>>> for loop, i in looper([1, 2, 3]):
... print loop.previous, loop.item, loop.index, loop.next, loop.first, loop.last, loop.length, loop.odd, loop.even
...
None 1 0 2 True False 3 True 0
1 2 1 3 False False 3 False 1
2 3 2 None False True 3 True 0
ソリューションをイテラブルで機能させたい場合は、itertools
ドキュメントに、使用したいことを正確に行うレシピがありますitertools.tee()
。
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
特に反復可能がジェネレーターになる可能性があるため(戻ることはできません)、簡単な方法はないと思います。要素のインデックスをループ本体に渡すことにより、シーケンスでそれを行うことができます。
for index, item in enumerate(l):
if index > 0:
previous_item = l[index - 1]
else:
previous_item = None
enumerate()
関数は組み込みです。
直前?
次のことですよね?
previous = None
for item in someList:
if item == target: break
previous = item
# previous is the item before the target
n 個の前のアイテムが必要な場合は、サイズ n の一種の循環キューでこれを行うことができます。
queue = []
for item in someList:
if item == target: break
queue .append( item )
if len(queue ) > n: queue .pop(0)
if len(queue ) < n: previous = None
previous = previous[0]
# previous is *n* before the target
イテレータには next() メソッドしかないため、前後を参照することはできず、次の項目しか取得できません。
enumerate(iterable) は、リストまたはタプルを反復する場合に役立ちます。
あまりpythonicではありませんが、それを成し遂げて簡単です:
l=[1,2,3]
for index in range(len(l)):
if l[index]==2:
l[index-1]
TO DO: エッジを保護する
最も簡単な方法は、アイテムのリストを検索することです。
def get_previous(l, item):
idx = l.find(item)
return None if idx == 0 else l[idx-1]
もちろん、これはリストに一意のアイテムのみが含まれている場合にのみ機能します。他の解決策は次のとおりです。
for idx in range(len(l)):
item = l[idx]
if item == 2:
l[idx-1]