2013-03-21 60 views
12

爲什麼下面的Python代碼引發錯誤
TypeError: type object argument after * must be a sequence, not generator
而如果我評論在發電機f頭(沒用)線,一切工作正常?類型錯誤:*後的對象類型參數必須是一個序列,而不是發電機

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.我實際上試圖做的是,使用單個生成器,返回多個迭代器(儘可能多地將其作爲參數傳遞給生成器)。我發現這樣做的唯一方法是產生元組並在其上使用izip() - 對我來說是黑魔法。

+0

您可能會發現'從itertools有趣tee' ... – Tathagata 2015-04-08 15:30:44

+0

'tee'必須通過運行和存儲所有元素一次,纔可以重複迭代,比照文檔:https://docs.python.org/3.1/library/itertools.html#itertools.tee。不幸的是沒有魔法,我在這裏的嘗試是天真的。 – JulienD 2015-10-16 23:56:09

回答

26

這是有趣:你忘了打電話給z當你把它傳遞給f

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

所以f試圖遍歷一個函數對象:

for _ in z: pass # z is a function 

這就提出一個TypeError:

TypeError: 'function' object is not iterable 

Python innards caught它和一個令人困惑的錯誤消息reraised。

# 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

的確,請參閱http://bugs.python.org/issue4806 – georg 2013-03-21 23:16:53

+0

四年來,哇。 – 2013-03-21 23:17:39

+0

非常感謝你! – JulienD 2013-03-21 23:18:43

相關問題