TypeError: аргумент объекта типа После * должен быть последовательностью, а не генератором

почему следующий код 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() на них-черная магия для меня.

1 ответов


это забавно: вы забыли позвонить z когда вы передали его f:

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

так f попытался перебрать объект функции:

for _ in z: pass  # z is a function

это вызвало TypeError:

TypeError: 'function' object is not iterable

внутренности Python поймали его и перезапустили с запутанным сообщением об ошибке.

# 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);
 ...