Bisherige Lösungen befassen sich nur mit Listen, und die meisten kopieren die Liste. Nach meiner Erfahrung ist das oft nicht möglich.
Sie befassen sich auch nicht mit der Tatsache, dass Sie wiederholte Elemente in der Liste haben können.
Der Titel Ihrer Frage lautet " Vorherige und nächste Werte in einer Schleife ". Wenn Sie jedoch die meisten Antworten hier in einer Schleife ausführen, wird die gesamte Liste für jedes Element erneut durchlaufen, um sie zu finden.
Also habe ich gerade eine Funktion erstellt, die. Unter Verwendung des itertools
Moduls wird das iterable geteilt und in Scheiben geschnitten und Tupel mit dem vorherigen und dem nächsten Element zusammen generiert. Nicht genau das, was Ihr Code tut, aber es lohnt sich, einen Blick darauf zu werfen, da er wahrscheinlich Ihr Problem lösen kann.
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)
Verwenden Sie es dann in einer Schleife, und Sie haben vorherige und nächste Elemente darin:
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
Die Ergebnisse:
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
Es funktioniert mit jeder Größenliste (da die Liste nicht kopiert wird) und mit jeder iterierbaren Liste (Dateien, Mengen usw.). Auf diese Weise können Sie einfach die Sequenz durchlaufen und die vorherigen und nächsten Elemente in der Schleife verfügbar machen. Sie müssen nicht erneut nach dem Element in der Sequenz suchen.
Eine kurze Erklärung des Codes:
tee
wird verwendet, um effizient 3 unabhängige Iteratoren über die Eingabesequenz zu erstellen
chain
verbindet zwei Sequenzen zu einer; es ist hier verwendet , um ein Einzelelement - Sequenz anhängen [None]
zuprevs
islice
wird verwendet, um eine Folge aller Elemente außer dem ersten chain
zu erstellen , und wird dann verwendet, um ein None
an sein Ende anzuhängen
- Es gibt jetzt 3 unabhängige Sequenzen
some_iterable
, die wie folgt aussehen:
prevs
:: None, A, B, C, D, E
items
:: A, B, C, D, E
nexts
:: B, C, D, E, None
- wird schließlich
izip
verwendet, um 3 Sequenzen in eine Sequenz von Tripletts zu ändern.
Beachten Sie, dass dies izip
stoppt, wenn eine Eingabesequenz erschöpft ist, sodass das letzte Element von prevs
ignoriert wird, was korrekt ist - es gibt kein solches Element, das das letzte Element sein würde prev
. Wir könnten versuchen, die letzten Elemente zu entfernen, prevs
aber izip
das Verhalten macht dies überflüssig
Beachten Sie auch , dass tee
, izip
, islice
und chain
kommen aus dem itertools
Modul; Sie arbeiten ihre Eingabesequenzen im laufenden Betrieb (träge), was sie effizient macht und nicht die Notwendigkeit mit sich bringt, die gesamte Sequenz zu jedem Zeitpunkt auf einmal im Speicher zu haben.
In python 3
wird beim Importieren ein Fehler angezeigt izip
, den Sie zip
anstelle von verwenden können izip
. Keine Notwendigkeit zu importieren zip
, ist es vordefiniert in python 3
- Quelle