Ich habe zwei Iterables in Python, und ich möchte sie paarweise durchgehen:
foo = (1, 2, 3)
bar = (4, 5, 6)
for (f, b) in some_iterator(foo, bar):
print "f: ", f, "; b: ", b
Das Ergebnis sollte sein:
f: 1; b: 4
f: 2; b: 5
f: 3; b: 6
Eine Möglichkeit ist, über die Indizes zu iterieren:
for i in xrange(len(foo)):
print "f: ", foo[i], "; b: ", b[i]
Aber das erscheint mir etwas unpythonisch. Gibt es einen besseren Weg?
for f, b in zip(foo, bar):
print(f, b)
zip
hört auf, wenn die kürzere der beiden Varianten foo
oder bar
aufhört.
In Python 3 gibt zip
einen Iterator von Tupeln zurück, wie itertools.izip
in Python2. Um eine Liste
von Tupeln zu erhalten, verwenden Sie list(zip(foo, bar))
. Und um zu zippen, bis beide Iteratoren erschöpft sind
erschöpft sind, würden Sie verwenden
itertools.zip_longest.
In Python 2 gibt zip
eine Liste von Tupeln zurück. Das ist in Ordnung, wenn foo
und bar
nicht massiv sind. Wenn sie beide massiv sind, dann ist die Bildung von zip(foo,bar)
eine unnötig massive
temporäre Variable und sollte ersetzt werden durch itertools.izip
oder
itertools.izip_longest
ersetzt werden, das einen Iterator statt einer Liste zurückgibt.
import itertools
for f,b in itertools.izip(foo,bar):
print(f,b)
for f,b in itertools.izip_longest(foo,bar):
print(f,b)
izip
hält an, wenn entweder foo
oder bar
erschöpft ist.
izip_longest
hört auf, wenn sowohl foo
als auch bar
erschöpft sind.
Wenn der/die kürzere(n) Iterator(en) erschöpft sind, liefert izip_longest
ein Tupel mit None
an der Position, die diesem Iterator entspricht. Sie können auch einen anderen Füllwert
als None
setzen, wenn Sie wollen. Siehe hier für die vollständige Geschichte.
Beachten Sie auch, dass zip
und seine zip
-ähnlichen Abkömmlinge eine beliebige Anzahl von Iterablen als Argumente akzeptieren können. Zum Beispiel,
for num, cheese, color in zip([1,2,3], ['manchego', 'stilton', 'brie'],
['red', 'blue', 'green']):
print('{} {} {}'.format(num, color, cheese))
druckt
1 red manchego
2 blue stilton
3 green brie
Sie benötigen die Funktion zip
.
for (f,b) in zip(foo, bar):
print "f: ", f ,"; b: ", b
Sie sollten die Funktion 'zip' verwenden. Hier ist ein Beispiel, wie Ihre eigene zip-Funktion aussehen kann
def custom_zip(seq1, seq2):
it1 = iter(seq1)
it2 = iter(seq2)
while True:
yield next(it1), next(it2)