2012-06-12 16 views
5

Obie listy i obiekty islice są iterowalne, ale dlaczego ta różnica w wyniku.funkcja tee z biblioteki 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] 
#[] 

Odpowiedz

14

Kwestia jest taka, że ​​tee() potrzeby spożywać wartości z oryginalnego iteracyjnej, jeśli zaczniesz zużywa je z oryginalnego iterator, to będzie w stanie funkcjonować prawidłowo. W Twojej przykładowej liście iteracja po prostu zaczyna się od nowa. W przykładzie generatora jest on wyczerpany i nie są generowane żadne inne wartości.

Jest to dobrze udokumentowane:

Po tee() dokonał rozłamu, oryginalny iterable nie powinny być wykorzystywane w innym miejscu; w przeciwnym razie, iteracja może być zaawansowana bez informowania o tych obiektach.

Source

Edytuj, aby zilustrować punkt w różnicy między listą i generatora:

>>> 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

, ale obiekt listy i obiekt islice muszą zachowywać się podobnie, prawda? – John

+1

@John Nie, po pętli nad listą otrzymujesz za każdym razem nowy iterator, co oznacza, że ​​wciąż otrzymujesz wartości. Gdy użyjesz 'islice()', otrzymasz generator, który wytworzy wartości raz, a następnie zostanie wyczerpany. Spróbuj sam - wystarczy dwukrotnie przelotować nad listą, a następnie dwukrotnie wykonać pętlę islice i zwrócić uwagę na różnicę w zachowaniu. –

+0

@John Aby oba przykłady zachowywały się podobnie, należy użyć 'r = iter ([1,2,3,4]) zamiast' r = [1,2,3,4] '. – clacke

0

na liście listowe, chcesz zastąpić r z i1.

Powiązane problemy