2013-01-31 15 views
8

Widzę dziwne zachowanie podczas pracy z funkcją zip(). Kiedy wykonuję następującą operację len (list (z)), gdzie z jest obiektem zip, wynikiem jest 0 (co wydaje mi się błędne), a akcja wydaje się usuwać obiekt zip. Czy ktoś może mi pomóc zrozumieć, co się dzieje.Wykonywanie len na liście obiektu zip usuwa zip

# python3 
Python 3.2.3 (default, Sep 30 2012, 16:41:36) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> w = [11, 22, 33, 44, 55, 66] 
>>> x = [1, 2, 3, 4] 
>>> y = ['a', 'b', 'c'] 
>>> z = zip(x, y, w) 
>>> z 
<zip object at 0x7f854f613cb0> 
>>> list(z) 
[(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)] 
>>> len(list(z)) 
0 
>>> list(z) 
[] 
>>> z 
<zip object at 0x7f854f613cb0> 
>>> 

Dziękuję, Ahmed.

Odpowiedz

11

W języku Python 3 zip is a generator. Generator jest wyczerpany, gdy wykonujesz list(z). Możesz utworzyć listę z wartości zwróconych przez generator i działać na nim.

l = list(z) 
len(l) 
# -> 3 
l 
# -> [(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)] 

Generators są dobrą rzeczą. Pozwalają nam napisać efektywny pod względem pamięci kod w niemal taki sam sposób, w jaki napisalibyśmy kod obsługujący listy. By posłużyć się przykładem z połączonego wiki:

def double(L): 
    return [x*2 for x in L] 

Może być zapisane jako generator, aby uniknąć tworzenia innej listy pamięć:

def double(L): 
    for x in L: 
     yield x*2 
+2

Dla każdego, kto jest używany tylko do Python 3, w Pythonie 2.x zip zwraca listę krotek. – TimothyAWiseman

+2

Dzięki za dodanie tego. Także 'zip() Pythona 3 działa jak 2.x' itertools.izip() ' – bernie

+0

Oczywiście, możesz napisać' double' jako 'double = (x * 2 dla xw L)' –

3

aby zakończyć poprzednią odpowiedź, istnieje biblioteka Pythona o nazwie cardinality dla uzyskania rozmiaru iterables.

http://cardinality.readthedocs.io/en/latest/