python iterator - Wie man zwei Listen parallel durchläuft?



hasnext iterable (7)

Ich habe zwei Iterables in Python, und ich möchte sie paarweise betrachten:

foo = (1, 2, 3)
bar = (4, 5, 6)

for (f, b) in some_iterator(foo, bar):
    print "f: ", f, "; b: ", b

Es sollte ergeben:

f: 1; b: 4
f: 2; b: 5
f: 3; b: 6

Eine Möglichkeit besteht darin, über die Indizes zu iterieren:

for i in xrange(len(foo)):
    print "f: ", foo[i], "; b: ", b[i]

Aber das scheint mir etwas unpythonisch. Gibt es einen besseren Weg, es zu tun?


Answers

Sie sollten die ' zip -Funktion 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)

def ncustom_zip(seq1,seq2,max_length):
        length= len(seq1) if len(seq1)>len(seq2) else len(seq2) if max_length else len(seq1) if len(seq1)<len(seq2) else len(seq2)
        for i in range(length):
                x= seq1[i] if len(seq1)>i else None  
                y= seq2[i] if len(seq2)>i else None
                yield x,y


l=[12,2,3,9]
p=[89,8,92,5,7]

for i,j in ncustom_zip(l,p,True):
        print i,j
for i,j in ncustom_zip(l,p,False):
        print i,j

for f, b in zip(foo, bar):
    print(f, b)

zip stoppt, wenn der kürzere von foo oder bar stoppt.

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 das Bilden von zip(foo,bar) eine unnötig massive temporäre Variable und sollte durch itertools.izip oder itertools.izip_longest , was einen Iterator anstelle 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 stoppt, wenn entweder foo oder bar erschöpft ist. izip_longest stoppt, wenn sowohl foo als auch bar erschöpft sind. Wenn die kürzeren Iteratoren erschöpft sind, liefert izip_longest ein Tupel mit None an der Position, die diesem Iterator entspricht. Sie können auch einen anderen fillvalue None fillvalue wenn Sie möchten. Sehen Sie hier für die ganze Geschichte .

In Python 3 gibt zip einen Iterator von Tupeln zurück, wie itertools.izip in Python2. Verwenden Sie die list(zip(foo, bar)) um eine Liste der Tupel zu erhalten. Und um zu zippen, bis beide Iteratoren erschöpft sind, würden Sie itertools.zip_longest .

Beachten Sie auch, dass zip und sein zip ähnliches Brethen eine beliebige Anzahl von Iterablen als Argumente akzeptieren können. Beispielsweise,

for num, cheese, color in zip([1,2,3], ['manchego', 'stilton', 'brie'], 
                              ['red', 'blue', 'green']):
    print('{} {} {}'.format(num, color, cheese))

Drucke

1 red manchego
2 blue stilton
3 green brie

Was du suchst, heißt zip .


Der eingebaute zip macht genau das, was Sie wollen. Wenn Sie das gleiche über iterables anstelle von Listen möchten, können Sie itertools.izip betrachten, das dasselbe tut, aber Ergebnisse nacheinander liefert.


Sie möchten die zip Funktion.

for (f,b) in zip(foo, bar):
    print "f: ", f ,"; b: ", b

Fügen Sie zwei Listen in Python hinzu:

>>> a = [1, 2, 3, 4]
>>> b = [1, 4, 6, 7]
>>> c = a + b
>>> c
[1, 2, 3, 4, 1, 4, 6, 7]

Wenn Sie keine Duplizierung wünschen:

>>> a = [1, 2, 3, 4, 5, 6]
>>> b = [5, 6, 7, 8]
>>> c = list(set(a + b))
>>> c
[1, 2, 3, 4, 5, 6, 7, 8]




python iterator