web-dev-qa-db-ja.com

リストを循環しながら次の要素を取得する

li = [0, 1, 2, 3]

running = True
while running:
    for elem in li:
        thiselem = elem
        nextelem = li[li.index(elem)+1]

これが最後の要素に到達すると、IndexErrorが発生します(リスト、タプル、辞書、または反復される文字列の場合)。その時点で、nextelemli[0]に等しくなるようにしたいのです。これに対するかなり面倒な解決策は

while running:
    for elem in li:
        thiselem = elem
        nextelem = li[li.index(elem)-len(li)+1]   # negative index

これを行うより良い方法はありますか?

41
ignoramus

これを慎重に検討した後、これが最良の方法だと思います。 breakを使用せずに簡単に途中で降りることができますが、これは重要だと思います。また、最小限の計算しか必要としないため、最速だと思います。また、liがリストまたはタプルである必要もありません。任意のイテレータを使用できます。

_from itertools import cycle

li = [0, 1, 2, 3]

running = True
licycle = cycle(li)
# Prime the pump
nextelem = next(licycle)
while running:
    thiselem, nextelem = nextelem, next(licycle)
_

後世のために他のソリューションをここに残します。

その派手なイテレータにはすべて場所がありますが、ここにはありません。 %演算子を使用します。

_li = [0, 1, 2, 3]

running = True
while running:
    for idx, elem in enumerate(li):
        thiselem = elem
        nextelem = li[(idx + 1) % len(li)]
_

ここで、リストを無限に循環させる場合は、次のようにします。

_li = [0, 1, 2, 3]

running = True
idx = 0
while running:
    thiselem = li[idx]
    idx = (idx + 1) % len(li)
    nextelem = li[idx]
_

それはteeを含む他のソリューションよりも理解しやすく、おそらくより高速だと思います。リストのサイズが変わらないことが確実な場合は、len(li)のコピーを削除して使用できます。

これにより、バケツが再び下に落ちるのを待たずに、中央の観覧車から簡単に降りることができます。他のソリューション(あなたのものを含む)では、runningループの途中でforをチェックしてから、breakをチェックする必要があります。

72
Omnifarious
while running:
    for elem,next_elem in Zip(li, li[1:]+[li[0]]):
        ...
14
John La Rooy

ペアごとの巡回反復子を使用できます。

from itertools import izip, cycle, tee

def pairwise(seq):
    a, b = tee(seq)
    next(b)
    return izip(a, b)

for elem, next_elem in pairwise(cycle(li)):
    ...
7
Ants Aasma

PythonでZipメソッドを使用します。この関数は、タプルのリストを返します。i番目のタプルには、各引数シーケンスまたは反復可能要素からのi番目の要素が含まれます。

    while running:
        for thiselem,nextelem in Zip(li, li[1 : ] + li[ : 1]):
            #Do whatever you want with thiselem and nextelem         
5
Nirmal
while running:
    lenli = len(li)
    for i, elem in enumerate(li):
        thiselem = elem
        nextelem = li[(i+1)%lenli]
3
Ned Batchelder

これを解決するためのかなり異なる方法:

   li = [0,1,2,3]

   for i in range(len(li)):

       if i < len(li)-1:

           # until end is reached
           print 'this', li[i]
           print 'next', li[i+1]

       else:

           # end
           print 'this', li[i]
3
Timothy Dalton
        li = [0, 1, 2, 3]
        for elem in li:
            if (li.index(elem))+1 != len(li):
                thiselem = elem
                nextelem = li[li.index(elem)+1]
                print 'thiselem',thiselem
                print 'nextel',nextelem
            else:
                print 'thiselem',li[li.index(elem)]
                print 'nextel',li[li.index(elem)]
0