2012-06-12 16 views
5

Tanto la lista como los objetos islice son iterables, pero esta diferencia en el resultado.función de la función de la biblioteca itertools

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] 
#[] 

Respuesta

14

La cuestión aquí es que tee() necesita consumir los valores del iterador original, si comienza a consumir desde el iterador original, que serán incapaces de funcionar correctamente. En su ejemplo de lista, la iteración simplemente comienza de nuevo. En el ejemplo del generador, está agotado y no se producen más valores.

Esto está bien documentado:

Una vez camiseta() ha hecho una división, el original iterables no deben utilizarse en ningún otro lugar; de lo contrario, el iterable podría avanzar sin que se informara a los objetos del tee.

Source

Editar 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) 
... 
>>> 
+0

pero el objeto de la lista y el objeto islice deben comportarse de manera similar, ¿no? – John

+1

@John No, cuando revisas la lista, obtienes un nuevo iterador cada vez, lo que significa que aún obtienes los valores. Cuando usas 'islice()' obtienes un generador, que producirá los valores una vez y luego se agotará. Pruébelo usted mismo, simplemente recorra dos veces una lista, luego tome un islice y repítalo dos veces, observe la diferencia en el comportamiento. –

+0

@John Para hacer que los dos ejemplos se comporten de manera similar, use 'r = iter ([1,2,3,4])' en lugar de 'r = [1,2,3,4]'. – clacke

0

En sus listas por comprensión, que desea reemplazar r con i1.

Cuestiones relacionadas