2013-03-21 9 views
12

Dlaczego następujący kod Python zgłasza błąd
TypeError: type object argument after * must be a sequence, not generator
natomiast gdybym skomentować pierwszy (bezużyteczny) Linia generator f, wszystko działa poprawnie?TypeError: typ obiektu argumentem po * muszą być sekwencją, nie generatora

from itertools import izip 

def z(): 
    for _ in range(10): 
     yield _ 

def f(z): 
    for _ in z: pass # if I comment this line it works! (??) 
    for x in range(10): 
     yield (x,10*x,100*x,1000*x) 

iterators = izip(*f(z)) 
for it in iterators: 
    print list(it) 

N.B. Naprawdę próbuję to zrobić, używając pojedynczego generatora, zwracając wiele iteratorów (tyle, ile przekazuję do generatora jako argumenty). Jedyny sposób, w jaki to zrobiłem, to wydać krotki i użyć na nich izip() - czarnej magii do mnie.

+0

Możecie znaleźć 'tee' z itertools ciekawych ... – Tathagata

+0

' tee' musi przebiegać przez i przechowywać wszystkie elementy kiedyś może powielać iterator, cf. dokumenty: https://docs.python.org/3.1/library/itertools.html#itertools.tee. Niestety nie ma magii, a moja próba była naiwna. – JulienD

Odpowiedz

26

To zabawne: zapomniałeś zadzwonić z gdy podał f:

iterators = izip(*f(z())) 

Więc f próbował iteracyjne nad obiekt funkcję:

for _ in z: pass # z is a function 

Ten podniósł TypeError:

TypeError: 'function' object is not iterable 

Złapane wgłębienie w języku Python to i przekreślone z mylącym komunikatem o błędzie.

# ceval.c 

static PyObject * 
ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) 
{ 
... 

      t = PySequence_Tuple(stararg); 
      if (t == NULL) { 
       if (PyErr_ExceptionMatches(PyExc_TypeError)) { 
        PyErr_Format(PyExc_TypeError, 
           "%.200s%.200s argument after * " 
           "must be a sequence, not %200s", 
           PyEval_GetFuncName(func), 
           PyEval_GetFuncDesc(func), 
           stararg->ob_type->tp_name); 
... 
+4

Rzeczywiście, zobacz http://bugs.python.org/issue4806 – georg

+0

Cztery lata, wow. –

+0

Och, dziękuję bardzo! – JulienD