防止生成器两次产生相同的对象

时间:2019-07-28 08:21:46

标签: python

假设我有一个生成器可产生哈希值(str / int等),有没有办法防止生成器两次生成相同的值?

很明显,我使用的是生成器,所以我不需要先解压所有值,所以yield from set(some_generator)之类的选项是不可行的,因为那样会解压整个生成器。

示例:

# Current result
for x in my_generator():
    print(x)

>>> 1
>>> 17
>>> 15
>>> 1   # <-- This shouldn't be here
>>> 15  # <-- This neither!
>>> 3
>>> ...

# Wanted result
for x in my_no_duplicate_generator():
    print(x)

>>> 1
>>> 17
>>> 15
>>> 3
>>> ...

最Python化的解决方案是什么?

2 个答案:

答案 0 :(得分:2)

您可以尝试以下方法:

def my_no_duplicate_generator(iterable):
    seen = set()
    for x in iterable:
        if x not in seen:
            yield x
            seen.add(x)

您可以通过将生成器作为参数来使用它:

for x in my_no_duplicate_generator(my_generator()):
    print(x)

答案 1 :(得分:2)

Python itertools模块食谱中有一个unique_everseen,大致相当于@NikosOikou的答案。

这些解决方案的主要缺点在于,它们依赖于以下假设:可迭代元素可散列:

>>> L = [[1], [2,3], [1]]
>>> seen = set()
>>> for e in L: seen.add(e)
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

more-itertools模块对实现进行了改进,以接受unhashables元素,并且文档提供了有关在某些情况下如何保持良好速度的提示(免责声明:我是提示的“作者”)。

您可以检查source code