50

ループでループしながら、次または前の要素listにアクセスする方法はありますか?tuplefor

l = [1, 2, 3]
for item in l:
    if item == 2:
        get_previous(l, item)
4

15 に答える 15

77

ジェネレータ関数として表現:

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
于 2008-11-27T14:28:23.527 に答える
34
l = [1, 2, 3]

for i, j in zip(l, l[1:]):
    print(i, j)
于 2014-05-08T01:10:28.057 に答える
12
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

于 2008-11-27T17:15:38.353 に答える
10

コンテキストが必要なジェネレーターを扱う場合、以下のユーティリティ関数を使用して、イテレーターにスライディング ウィンドウ ビューを表示することがよくあります。

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)
于 2008-11-27T14:29:16.303 に答える
8

私はこれが古いことを知っていますが、なぜ単に使用しないの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

これを実行すると、前のアイテムと次のアイテムが取得され、リスト内のアイテムの繰り返しは気にされないことがわかります。

于 2014-02-26T01:40:44.207 に答える
5

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
于 2008-11-28T14:21:20.083 に答える
3

ソリューションをイテラブルで機能させたい場合は、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)
于 2016-12-08T19:07:10.310 に答える
1

特に反復可能がジェネレーターになる可能性があるため(戻ることはできません)、簡単な方法はないと思います。要素のインデックスをループ本体に渡すことにより、シーケンスでそれを行うことができます。

for index, item in enumerate(l):
    if index > 0:
        previous_item = l[index - 1]
    else:
        previous_item = None 

enumerate()関数は組み込みです。

于 2008-11-27T13:55:31.177 に答える
1

直前?

次のことですよね?

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
于 2008-11-27T15:46:17.753 に答える
0

イテレータには next() メソッドしかないため、前後を参照することはできず、次の項目しか取得できません。

enumerate(iterable) は、リストまたはタプルを反復する場合に役立ちます。

于 2008-11-27T13:39:28.650 に答える
-2

あまりpythonicではありませんが、それを成し遂げて簡単です:

l=[1,2,3]
for index in range(len(l)):
    if l[index]==2:
        l[index-1]

TO DO: エッジを保護する

于 2011-01-12T18:50:54.037 に答える
-7

最も簡単な方法は、アイテムのリストを検索することです。

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]
于 2008-11-27T13:41:17.007 に答える