función tee de la biblioteca itertools

Tanto los objetos de lista como los de islice son iterables, pero ¿por qué esta diferencia en el resultado?

r = [1, 2, 3, 4]               
i1, i2 = tee(r)
print [e for e in r if e < 3]
print [e for e in i2]
#[1, 2]
#[1, 2, 3, 4]


r = islice(count(), 1, 5)          
i1, i2 = tee(r)
print [e for e in r if e < 3]
print [e for e in i2]
#[1, 2]
#[]

preguntado el 12 de junio de 12 a las 15:06

2 Respuestas

El problema aquí es que tee() necesita consumir los valores del iterador original, si comienza a consumirlos del iterador original, no podrá funcionar correctamente. En su ejemplo de lista, la iteración simplemente comienza de nuevo. En el ejemplo del generador, se agota y no se producen más valores.

Esto está bien documentado:

Una vez que tee() ha hecho una división, el iterable original no debe usarse en ningún otro lugar; de lo contrario, el iterable podría avanzar sin que se informe a los objetos tee.

Fuente

Edite para ilustrar el punto en la diferencia entre una lista y un generador:

>>> from itertools import islice, count
>>> a = list(range(5))
>>> b = islice(count(), 0, 5)
>>> a
[0, 1, 2, 3, 4]
>>> b
<itertools.islice object at 0x7fabc95d0fc8>
>>> for item in a:
...     print(item)
... 
0
1
2
3
4
>>> for item in a:
...     print(item)
... 
0
1
2
3
4
>>> for item in b:
...     print(item)
... 
0
1
2
3
4
>>> for item in b:
...     print(item)
... 
>>> 

Respondido el 12 de junio de 12 a las 17:06

pero el objeto de lista y el objeto de islice deben comportarse de manera similar, ¿verdad? - John

@John No, cuando recorre la lista, obtiene un nuevo iterador cada vez, lo que significa que aún obtiene los valores. cuando usas islice() obtienes un generador, que producirá los valores una vez y luego se agotará. Pruébelo usted mismo: simplemente recorra una lista dos veces, luego tome un islice y recorra eso dos veces; observe la diferencia en el comportamiento. - gareth latty

@John Para hacer que los dos ejemplos se comporten de manera similar, use r = iter([1,2,3,4]) más bien que r = [1,2,3,4]. - claqué

Si destruye iteradores desde el tee, ¿puede avanzar el iterador original? - Estuardo Axon

En su lista de comprensiones, desea reemplazar r con i1.

Respondido el 12 de junio de 12 a las 16:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.