我有一个错误是由于检查“if x in generator”
的变化结果造成的def primes(upper_limit):
for n in range(2, upper_limit):
if all(n % i > 0 for i in range(2, n)):
yield n
first_hundred_primes = primes(100)
print(5 in first_hundred_primes)
print(5 in first_hundred_primes)
print(5 in first_hundred_primes)
print(5 in first_hundred_primes)
print(5 in first_hundred_primes)
这给出了输出:
True
False
False
False
False
我假设一个并不是要检查一个对象是否存在于生成器中,但如果是这种情况,为什么它不会引发一些错误,为什么这会起作用呢?
>>> hundred_generator = range(1,100)
>>> 50 in hundred_generator
True
>>> 50 in hundred_generator
True
>>> 50 in hundred_generator
True
在我检查是否存在某个对象(加快检查)之前,我通常会将生成器变成一个集合,这样可以解决问题,但我非常想知道这里发生了什么?
答案 0 :(得分:6)
当您遍历生成器的元素时,使用它们。
试试这个:
len(list(first_hundred_primes)) > 0
=> True
len(list(first_hundred_primes)) > 0
=> False
即。你第一次使用in
(迭代它们)或者列出所有元素(最多5个)时你已经完成了元素的使用,因此生成器在此之后不再生成5。在第二次之后,它不再生成任何东西。
您的选择:
first_hundred_primes = list(first_hundred_primes)
5 in primes(100); 5 in primes(100); ...
itertools.tee
编辑:
关于range
的问题:range
不是生成器。
在python2中,它只返回一个列表。没问题。
在python3中,它返回一个看起来像集合的特殊对象。它不必实际存储范围内的所有数字,它只是根据定义范围的规则实现列表操作。例如。 len
已实施为stop-start
。因为它代表一个集合而不是一个生成器,所以你可以多次迭代它,而不需要消耗#34;元素。