【发布时间】:2012-10-22 18:13:27
【问题描述】:
我希望能够yield 可变数量的项目,这将允许编写类似于以下内容的生成器函数:
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))
添加的代码是因为我希望它也接受一个可选的不可迭代的最后一个参数来指定一个非 0 的起始值(或使用 start 关键字参数指定它),就像内置的一样enumerate()函数。
【问题讨论】:
-
您在寻找
zip还是izip? -
yield在某种意义上就像return- 你可以产生同样数量的东西,你可以返回。也就是说,一件事物,但你可以返回所有参数的元组。 -
如果您只想将迭代器组合到一个生成器中,请使用
itertools.izip -
@Makoto:是的,好点子。问题的关键是我没有意识到如果函数只是
yielded 一个 single 元组,那么它可以在接收端正确拆分。我接受的答案解决了这个问题,然后解决了一些问题。
标签: python generator enumerate