把成对发生器变成成对发生器

2024-06-16 11:10:13 发布

您现在位置:Python中文网/ 问答频道 /正文

如何启动成对(元组)生成器:

tuple_gen = (i for i in [(1, "a"), (2, "b"), (3, "c")])

将生成[1, 2, 3]和{}的两个生成器?在

我需要分别处理元组的第一个和第二个元素,处理函数需要iterable。在

生成器非常大(数百万个项),因此除非没有其他解决方案,否则我希望避免将所有项同时存储在内存中。在


Tags: 内存in元素for解决方案iterablegen元组
3条回答

您可以使用itertools进行如下操作:

>>>from itertools import chain, izip, imap
>>>tuple_gen = (i for i in [(1, "a"), (2, "b"), (3, "c")])
>>>nums_gen, letters_gen = imap(lambda x: chain(x), izip(*tuple_gen))
>>>list(nums_gen)
[1, 2, 3]
>>>list(letters_gen)
['a', 'b', 'c']

注意

对于python3izip将只是zipimap只是map

可以使用itertools包中的tee函数创建n个不同的迭代器。然后分别对它们进行迭代:

from itertools impor tee

i1, i2 = tee(tuple_gen, n=2)
firsts = (x[0] for x in i1)
seconds = (x[1] for x in i2)

这里有一个根本的问题。假设您得到了两个迭代器iter1iter2,然后将iter1传递给一个函数,该函数会吃掉整个内容:

def consume(iterable):
    for thing in iterable:
        do_stuff_with(thing)

consume(iter1)

这需要遍历所有tuple_gen来获得第一个项目,然后如何处理第二个项目?除非您可以重新运行生成器以再次获取第二个项目,否则您需要将所有这些项目存储在内存中,除非您可以将它们持久化到磁盘或其他东西中,因此,与将tuple_gen转储到列表中相比,这样做的好处并不多。在


如果您这样做,您必须并行使用迭代器,或者运行底层生成器两次,或者花费大量内存来保存未处理的元组元素,以便其他迭代器可以遍历它们。不幸的是,并行使用迭代器将需要重写使用者函数或在单独的线程中运行它们。如果可以的话,运行生成器两次是最简单的,但并不总是一个选项。在

相关问题 更多 >