是否有使用嵌套迭代器的意义?

时间:2014-11-17 04:51:33

标签: python performance iterator itertools

我正在阅读我的一些旧代码并遇到了这一行

itertools.starmap(lambda x,y: x + (y,), 
                  itertools.izip(itertools.repeat(some_tuple, 
                                                  len(list_of_tuples)),
                                 itertools.imap(lambda x: x[0],
                                                list_of_tuples)))

要清楚,我有一些list_of_tuples我希望从每个元组中获取第一个项目(itertools.imap),我有另一个要重复的元组({{1 }}}这样,itertools.repeat中的每个元组都有一个副本,然后我希望根据list_of_tupleslist_of_tuples)中的项目获得新的,更长的元组。

例如,假设itertools.starmapsome_tuple = (1, 2, 3)。我想要像list_of_tuples = [(1, other_info), (5, other), (8, 12)]这样的东西。这不是确切的IO(它使用了一些非常不相关和复杂的类),而我的实际列表和元组非常大。

有没有必要像这样嵌套迭代器?在我看来,像itertools中的每个函数都必须迭代我给它的迭代器并在某处存储信息,这意味着将其他迭代器放在[(1, 2, 3, 1), (1, 2, 3, 5), (1, 2, 3, 8)]中没有任何好处。我完全错了吗?这是如何工作的?

2 个答案:

答案 0 :(得分:2)

没有理由嵌套迭代器。使用变量不会对性能/内存产生明显影响:

first_items = itertools.imap(lambda x: x[0], list_of_tuples)
repeated_tuple = itertools.repeat(some_tuple, len(list_of_tuples))
items = itertools.izip(repeated_tuple, first_items)
result = itertools.starmap(lambda x,y: x + (y,), items)

itertools使用和返回的迭代器对象不会将所有项存储在内存中,而只是在需要时计算下一个项。您可以详细了解它们的工作原理here

答案 1 :(得分:1)

在这种情况下,我不相信上面的组合是必要的。

它似乎等同于这个生成器表达式:

(some_tuple + (y[0],) for y in list_of_tuples)

然而,偶尔itertools可以在cpython中具有性能优势