【问题标题】:itertools.tee not making copies of groupby iteratoritertools.tee 没有复制 groupby 迭代器
【发布时间】:2020-05-11 21:15:42
【问题描述】:

我刚刚了解到itertools.tee() 可用于制作给定迭代器的任意数量的副本。

所以我正在尝试创建两个 groupby 副本并遍历每个副本。但是,第二个迭代器不返回任何组。

import itertools
l = [("a", 1), ("a", 2), ("b", 3), ("b", 4)]
groups = itertools.groupby(l, lambda x: x[0])

groups1, groups2 = itertools.tee(groups, 2)

for key, group in groups1:
    print(key + ": " + str(list(group)))

for key, group in groups2:
    print(key + ": " + str(list(group)))

另外,我在文档中发现了这一点,我无法完全理解 tee() 何时不比 list()

这个 itertool 可能需要大量的辅助存储(取决于 需要存储多少临时数据)。一般来说,如果一个 迭代器在另一个迭代器启动之前使用大部分或全部数据, 使用 list() 而不是 tee() 更快。

任何帮助将不胜感激。谢谢!

【问题讨论】:

标签: python itertools


【解决方案1】:

groupby 是一个嵌套迭代器; “outer”返回一系列_grouper 对象,每个对象也是一个迭代器。你tee 外部的成功了,但是内部的迭代器没有被复制,所以它们在第一个循环中被耗尽了。如果您注意到,您的第二个循环确实打印出每个组的键,只是组本身是空的。


另外,关于 listtee - tee 所做的是从底层迭代器中获取每个项目并保存它的 n 个副本。随着每个独立迭代器的前进,它对特定项目的副本可能会被丢弃。如果您同步推进所有副本,这很好。但是如果你例如完全耗尽一个副本而不触及任何其他副本,您实际上只是创建了原始迭代器的n 完整副本。

如文档所述:

一般来说,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,那么使用 list() 而不是 tee() 会更快。

【讨论】:

  • 非常感谢!知道了!那么有没有更好的方法来实现我正在寻找的东西(在内存方面有效地循环两次组)?我想我应该调用 groupby 两次并创建 2 个 groupby 迭代器。但这不会浪费计算吗?没有办法完全复制迭代器吗?
  • @Stuxen 我只会做两次 GroupBy。这是一个非常便宜的操作,因为它只是查看下一个元素是否匹配。复制结果可能会很慢。如果你想尝试一下,你可以在这里成功使用copy.deepcopy
猜你喜欢
  • 2020-07-08
  • 2019-05-28
  • 1970-01-01
  • 2019-05-16
  • 2015-01-01
  • 1970-01-01
  • 2019-01-06
  • 2017-07-05
  • 2018-01-28
相关资源
最近更新 更多