返回一个像zip这样的元组列表,使用理解逐步生成一个元组

时间:2014-01-24 15:09:41

标签: python generator

我需要一个函数,它不使用zip就从序列列表中一次返回一个元组。我试图以这种方式做到:

gen1=[(x,y)for x in range(3) for y in range(4)]

给出以下列表:

[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]

接下来我尝试通过以下方式一次返回一个元组:

next(gen1)

但是发生了错误,该列表不是“可迭代的”。我怎么能用发电机来做呢。

2 个答案:

答案 0 :(得分:1)

从Python 2.4开始,您可以:

gen1 = ((x, y) for x in range(3) for y in range(4))

请注意,您始终可以使用iter的列表创建生成器(井,迭代器):

gen1 = iter([(x, y) for x in range(3) for y in range(4)])

使用上的差异将是无。第二种方式需要整个列表在内存中,而第一种方法则不需要。

请注意,您还可以使用zip的内置功能,它是一个生成器(在Python 3中)。在Python 2中,使用itertools.izip

Python 3:

>>> zip(range(0, 5), range(3, 8))
<zip object at 0x7f07519b3b90>
>>> list(zip(range(0, 5), range(3, 8)))
[(0, 3), (1, 4), (2, 5), (3, 6), (4, 7)]

Python&lt; 3:

# Python < 3
>>> from itertools import izip
>>> izip(range(0, 5), range(3, 8))
<itertools.izip object at 0x7f5247807440>
>>> list(izip(range(0, 5), range(3, 8)))
[(0, 3), (1, 4), (2, 5), (3, 6), (4, 7)]
>>> zip(range(0, 5), range(3, 8))
[(0, 3), (1, 4), (2, 5), (3, 6), (4, 7)]

答案 1 :(得分:1)

如果你希望行为使用任意数量的序列,虽然问题中仍有一些含糊之处,如果你想要做的只是制作zip的生成器版本,下面应该可以正常工作:

def generator_zip(*args):
    iterators = map(iter, args)
    while iterators:
        yield tuple(map(next, iterators))

首先它将每个arg转换为迭代器,然后继续生成包含每个迭代器的下一个相关条目的元组,直到最短列表用完为止。