使用嵌套迭代器有啥意义吗?
Posted
技术标签:
【中文标题】使用嵌套迭代器有啥意义吗?【英文标题】:Is there a point to using nested iterators?使用嵌套迭代器有什么意义吗? 【发布时间】:2014-11-17 04:51:32 【问题描述】:我正在阅读我的一些旧代码并遇到了这一行
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
),我还有另一个我想重复的元组(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)]
。我想要[(1, 2, 3, 1), (1, 2, 3, 5), (1, 2, 3, 8)]
之类的东西。这不是确切的 IO(它使用了一些非常不相关和复杂的类),而且我的实际列表和元组非常大。
这样嵌套迭代器有什么意义吗?在我看来,来自 itertools 的每个函数都必须遍历我给它的迭代器,并将其中的信息存储在某个地方,这意味着将其他迭代器放在 starmap
内没有任何好处。我完全错了吗?这是如何工作的?
【问题讨论】:
如果您向我们展示预期的输入和输出将很好地映射您的工作 不,原因很简单,它使代码难以理解。保持简单 @gnibbler 可能是这样,即使删除它仍然会得到我们嵌套的迭代器,所以除非删除它会改变答案,否则我仍然想知道是否有一般嵌套的意义 @Dannnno,如果你真的很小心,使用 itertools 可以获得性能提升。不过这里不太可能是这种情况。 【参考方案1】:没有理由嵌套迭代器。使用变量不会对性能/内存产生明显影响:
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。
【讨论】:
我认为这正是我的问题所要问的。我不确定如果不嵌套迭代器,我最终会在内存中存储比我想要的更多的东西。谢谢!【参考方案2】:我不认为在这种情况下上述组合是必要的。
它似乎等同于这个生成器表达式:
(some_tuple + (y[0],) for y in list_of_tuples)
然而,itertools 有时会具有性能优势,尤其是在 cpython 中
【讨论】:
所以忽略我给出的例子,我可以看到这不是一个好的例子,一般来说,迭代器的嵌套会对程序的性能产生任何积极的或其他的影响吗?还是必须根据具体情况来决定? @Dannnno,您应该更喜欢以最易读的方式编写代码。如果它被证明是一个性能瓶颈,你可以用任何你认为更快的方式重写它。保留易于阅读的版本作为文档。您可以针对这两个版本编写单元测试,以检测行为是否在您的更快版本中意外更改以上是关于使用嵌套迭代器有啥意义吗?的主要内容,如果未能解决你的问题,请参考以下文章