Jud*_*ing 1 python list generator range
我有一个错误是由检查"如果x在发电机中"的变化结果引起的
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)
Run Code Online (Sandbox Code Playgroud)
这给出了输出:
True
False
False
False
False
Run Code Online (Sandbox Code Playgroud)
我假设一个不是要检查一个对象是否存在于生成器中,但如果是这种情况,为什么它不会抛出一些错误,为什么这个工作?
>>> hundred_generator = range(1,100)
>>> 50 in hundred_generator
True
>>> 50 in hundred_generator
True
>>> 50 in hundred_generator
True
Run Code Online (Sandbox Code Playgroud)
在我检查是否存在某个对象(加快检查)之前,我通常会将生成器变成一个集合,这样可以解决问题,但我非常想知道这里发生了什么?
当您遍历生成器的元素时,您将使用它们.
试试这个:
len(list(first_hundred_primes)) > 0
=> True
len(list(first_hundred_primes)) > 0
=> False
Run Code Online (Sandbox Code Playgroud)
也就是说,你第一次使用元素时会消耗元素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.由于它代表集合而不是生成器,因此您可以多次迭代它,而不会"消耗"元素.