Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 可变长度';收益率';?_Python_Generator_Enumerate - Fatal编程技术网

Python 可变长度';收益率';?

Python 可变长度';收益率';?,python,generator,enumerate,Python,Generator,Enumerate,我希望能够产生一个可变数量的项目,允许编写一个生成器函数,如以下所示: x = [1, 2, 3] y = [4, 5, 6] z = [7, 8, 9] def multi_enumerate(*iterables): n = 0 iterators = map(iter, iterables) while iterators: yield n, *tuple(map(next, iterators)) # invalid syntax

我希望能够
产生
一个可变数量的项目,允许编写一个生成器函数,如以下所示:

x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]

def multi_enumerate(*iterables):
    n = 0
    iterators = map(iter, iterables)
    while iterators:
        yield n, *tuple(map(next, iterators))  # invalid syntax
        n += 1

for i,a,b,c in multi_enumerate(x, y, z):
    print i,a,b,c
有人知道这样做的方法吗?我知道我可以生成一个元组,但这需要在接收端显式地解包,例如:
a,b,c=t[0],t[1],t[2]

最终解决方案

FWIW,根据约翰·库格曼(John Kugelman)出色的回答,我最终使用了以下内容:

from itertools import izip

def multi_enumerate(*iterables, **kwds):
    start = kwds.get('start')
    if start is None:
        if kwds: raise TypeError(
            "multi_enumerate() accepts only the keyword argument 'start'")
        try:
            iter(iterables[-1])  # last non-keyword arg something iterable?
        except TypeError:        # no, assume it's the start value
            start, iterables = iterables[-1], iterables[:-1]
        else:
            start = 0  # default

    return ((n,)+t for n, t in enumerate(izip(*iterables), start))

添加的代码是因为我希望它也接受一个可选的不可iterable last参数,以指定除0以外的起始值(或使用
start
关键字参数指定),就像内置的
enumerate()
函数一样。

yield
语句更改为:

yield (n,) + tuple(map(next, iterators))
或者使用
izip
enumerate
消除整个循环:

from itertools import izip

def multi_enumerate(*iterables):
    return ((n,) + t for n, t in enumerate(izip(*iterables)))
我将从以下位置使用:


这将返回一个迭代器,为
i
n
-length
l
s生成
(n,*l[n])
。它将直接取代您的
多重枚举
方法

from itertools import izip
def enumerated_columns(*rows):
    return izip(range(len(rows[0])), *rows)
如果您想将多个项目从生成器委托给其他生成器,那么没有一种单行方式可以做到这一点,除非您使用Python 3.3

我将迭代嵌套的生成器,从中显式地生成值,类似于

yield n
for value in (delegated.next for delegated in iterators):
  yield value

你是在寻找
zip
还是
izip
收益
在某种意义上就像
return
——你可以产生与你可以返还的数量相同的东西。这就是说,有一件事,但您可以返回所有参数的元组。如果您只想将iterables合并到一个生成器中,请使用
itertools.izip
@Makoto:是的,这一点很好。问题的关键是我没有意识到,如果函数只
产生一个元组,那么它就可以在接收端正确地拆分。我接受的答案解决了这个问题,然后是一些问题。
yield n
for value in (delegated.next for delegated in iterators):
  yield value