Paarweise kreisförmige Python 'for'-Schleife
Wenn Ihnen die akzeptierte Antwort gefällt,
zip(L, L[1:] + L[:1])
Sie können mit semantisch demselben Code viel mehr Speicherlicht erzeugen, indem Sie Folgendes verwenden itertools:
from itertools import islice, chain
Und dies materialisiert kaum etwas im Speicher, das über die ursprüngliche Liste hinausgeht (vorausgesetzt, die Liste ist relativ groß):
zip(l, chain(islice(l, 1, None), islice(l, None, 1)))
Zum Verwenden verbrauchen Sie einfach (zum Beispiel mit einer Liste):
>>> list(zip(l, chain(islice(l, 1, None), islice(l, None, 1))))
[(1, 2), (2, 3), (3, 1)]
Dies kann auf jede Breite erweiterbar gemacht werden:
def cyclical_window(l, width=2):
return zip(*[chain(islice(l, i, None), islice(l, None, i)) for i in range(width)])
und Verwendung:
>>> l = [1, 2, 3, 4, 5]
>>> cyclical_window(l)
<itertools.izip object at 0x112E7D28>
>>> list(cyclical_window(l))
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)]
>>> list(cyclical_window(l, 4))
[(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 1), (4, 5, 1, 2), (5, 1, 2, 3)]
Unbegrenzte Generierung mit itertools.teemitcycle
Sie können auch verwenden tee, um zu vermeiden, dass ein redundantes Zyklusobjekt erstellt wird:
from itertools import cycle, tee
ic1, ic2 = tee(cycle(l))
next(ic2)
und nun:
>>> [(next(ic1), next(ic2)) for _ in range(10)]
[(1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2)]
Das ist unglaublich effizient, eine erwartete Nutzung itermit nextund eleganter Verwendung von cycle, teeund zip.
Gehen Sie nicht cycledirekt zu weiter, es listsei denn, Sie haben Ihre Arbeit gespeichert und haben Zeit, damit Ihr Computer zum Stillstand kommt, wenn Sie den Speicher voll ausschöpfen. Wenn Sie Glück haben, wird Ihr Betriebssystem den Prozess nach einer Weile abbrechen, bevor er Ihren Computer zum Absturz bringt .
Integrierte Python-Funktionen
Schließlich keine Standard-Lib-Importe, aber dies funktioniert nur bis zur Länge der ursprünglichen Liste (sonst IndexError.)
>>> [(l[i], l[i - len(l) + 1]) for i in range(len(l))]
[(1, 2), (2, 3), (3, 1)]
Sie können dies mit modulo fortsetzen:
>>> len_l = len(l)
>>> [(l[i % len_l], l[(i + 1) % len_l]) for i in range(10)]
[(1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2)]