Tengo dos iterables en Python, y quiero repasarlos en pares:
foo = (1, 2, 3)
bar = (4, 5, 6)
for (f, b) in some_iterator(foo, bar):
print "f: ", f, "; b: ", b
Debería resultar en:
f: 1; b: 4
f: 2; b: 5
f: 3; b: 6
Uno forma de hacerlo es iterar sobre los índices:
for i in xrange(len(foo)):
print "f: ", foo[i], "; b: ", b[i]
Pero eso me parece un poco antitético. Hay una mejor manera de hacerlo?
for f, b in zip(foo, bar):
print(f, b)
zip
se detiene cuando el más corto de foo
o bar
se detiene
En Python 2, zip
devuelve una lista de tuplas. Esto está bien cuando foo
y bar
no son masivos Si
ambos son masivos y luego forman zip(foo,bar)
es innecesariamente masivo
variable temporal, y debe ser reemplazado por itertools.izip
o
itertools.izip_longest
, que devuelve un iterador en lugar de una lista.
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
se detiene cuando foo
o bar
está agotado.
izip_longest
se detiene cuando ambos foo
y bar
están agotados
Cuando los iteradores más cortos están agotados, izip_longest
produce una tupla con None
en la posición correspondiente a ese iterador. También puede establecer un diferente fillvalue
además None
si lo desea. Vea aquí para el historia completa.
En Python 3, zip
devuelve un iterador de tuplas, como itertools.izip
en Python2. Para obtener una lista
de tuplas, use list(zip(foo, bar))
. Y para comprimir hasta que ambos iteradores estén
agotado, usarías
itertools.zip_longest.
Tenga en cuenta también que zip
y es zip
-como brethen puede aceptar un número arbitrario de iterables como argumentos. Por ejemplo,
for num, cheese, color in zip([1,2,3], ['manchego', 'stilton', 'brie'],
['red', 'blue', 'green']):
print('{} {} {}'.format(num, color, cheese))
huellas dactilares
1 red manchego
2 blue stilton
3 green brie
Quiere que el zip
función.
for (f,b) in zip(foo, bar):
print "f: ", f ,"; b: ", b
El builtin zip
hace exactamente lo que quieres Si desea el mismo sobre iterables en lugar de listas, puede mirar itertools.izip, que hace lo mismo pero da resultados de uno en uno.
Lo que estás buscando se llama zip
.
Deberías usar 'cremallera'función. Aquí hay un ejemplo de cómo su propia función zip se puede ver
def custom_zip(seq1, seq2):
it1 = iter(seq1)
it2 = iter(seq2)
while True:
yield next(it1), next(it2)
la función zip resuelve el problema
Documentos: Función de biblioteca ZIP
OBJETIVO: poner la salida al lado del otro
Problema:
#value1 is a list
value1 = driver.find_elements_by_class_name("review-text")
#value2 is a list
value2 = driver.find_elements_by_class_name("review-date")
for val1 in value1:
print(val1.text)
print "\n"
for val2 in value2:
print(val2.text)
print "\n"
Salida:
opinión 1
review2
reseña3
fecha1
fecha2
fecha3
Solución:
for val1, val2 in zip(value1,value2):
print (val1.text+':'+val2.text)
print "\n"
Salida:
review1: date1
review2: date2
review3: date3
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