Python - 没有消耗的迭代器中的计数元素

Apo*_*ica 2 python

给定一个迭代器it,我想要一个函数it_count,它返回迭代器产生的元素数,而不会破坏迭代器.例如:

ita = iter([1, 2, 3])
print(it_count(ita))
print(it_count(ita))
Run Code Online (Sandbox Code Playgroud)

应该打印

3
3
Run Code Online (Sandbox Code Playgroud)

有人指出,对于所有迭代器来说,这可能不是一个明确定义的问题,所以我不是在寻找一个完全通用的解决方案,但它应该在给定的例子中按预期运行.


好的,让我进一步澄清我的具体案例.给出以下代码:

ita = iter([1, 2, 3])
itb, itc = itertools.tee(ita)
print(sum(1 for _ in itb))
print(sum(1 for _ in itc))
Run Code Online (Sandbox Code Playgroud)

...我们可以编写it_count上面描述的函数,以便它以这种方式运行吗?即使问题的答案是"无法做到",这仍然是一个完全有效的答案.它不会让问题变得糟糕.并且证明它是不可能的将远非微不足道的......

use*_*ica 5

不可能.直到迭代器已经被完全消耗掉,它不会一个具体的元素计数.


Apo*_*ica 1

我无法提出精确的解决方案(因为迭代器可能是不可变类型),但这是我的最佳尝试。根据文档( 的最后一段) ,我相信第二个应该更快itertools.tee

选项1

def it_count(it):
   tmp_it, new_it = itertools.tee(it)
   return sum(1 for _ in tmp_it), new_it
Run Code Online (Sandbox Code Playgroud)

选项2

def it_count2(it):
   lst = list(it)
   return len(lst), lst
Run Code Online (Sandbox Code Playgroud)

它功能良好,但有一点烦恼,即返回对而不是简单的计数。

ita = iter([1, 2, 3])
count, ita = it_count(ita)
print(count)

Output: 3

count, ita = it_count2(ita)
print(count)

Output: 3

count, ita = it_count(ita)
print(count)

Output: 3

print(list(ita))

Output: [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)