我正在阅读我的一些旧代码并遇到了这一行
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_tuples
(list_of_tuples
)中的项目获得新的,更长的元组。
例如,假设itertools.starmap
和some_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)]
中没有任何好处。我完全错了吗?这是如何工作的?
答案 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中具有性能优势