webentwicklung-frage-antwort-db.com.de

Nächstes Element beim Durchlaufen einer Liste

li = [0, 1, 2, 3]

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

Wenn dieses Element das letzte Element erreicht, wird eine IndexError ausgelöst (wie bei jeder Liste, Tuple, Wörterbuch oder String, die wiederholt werden). Ich möchte an dieser Stelle, dass nextelem gleich li[0] ist. Meine ziemlich umständliche Lösung dafür war

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

Gibt es einen besseren Weg, dies zu tun?

35
ignoramus

Nach gründlicher Überlegung denke ich, dass dies der beste Weg ist. Sie können problemlos in die Mitte springen, ohne break zu verwenden, was ich für wichtig halte und wenig Rechenaufwand erfordert. Ich denke, es ist das schnellste. Es ist auch nicht erforderlich, dass li eine Liste oder ein Tuple ist. Es könnte ein beliebiger Iterator sein.

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)

Ich lasse die anderen Lösungen hier für die Nachwelt.

Das ganze schicke Iterator-Zeug hat seinen Platz, aber nicht hier. Verwenden Sie den Operator%.

li = [0, 1, 2, 3]

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

Wenn Sie eine Liste unendlich oft durchlaufen möchten, tun Sie dies einfach:

li = [0, 1, 2, 3]

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

Ich denke, das ist einfacher zu verstehen als die andere Lösung mit tee und wahrscheinlich auch schneller. Wenn Sie sicher sind, dass die Liste ihre Größe nicht ändert, können Sie eine Kopie von len(li) wegnehmen und diese verwenden.

So können Sie auch problemlos das Riesenrad in der Mitte verlassen, anstatt warten zu müssen, bis der Löffel wieder auf den Boden kommt. Bei den anderen Lösungen (einschließlich Ihrer) müssen Sie running in der Mitte der for-Schleife und dann break markieren.

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

Sie können einen paarweisen zyklischen Iterator verwenden:

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

Verwenden Sie die Zip-Methode in Python. Diese Funktion gibt eine Liste von Tupeln zurück, wobei der i-te Tupel das i-te Element aus jeder der Argumentsequenzen oder iterierbaren Elemente enthält

    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

Ein etwas anderer Weg, um das zu lösen: 

   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