Python 3.x Python:set(sympy.primerange(a,b))

Python 3.x Python:set(sympy.primerange(a,b)),python-3.x,sympy,Python 3.x,Sympy,(Python 3.5.1) 我一直在尝试使用Sympy解决一些Project Euler问题,但是我遇到了一些奇怪的问题,关于set(Sympy.primerange(a,b))和类似的构造是如何工作的 >>> import sympy >>> PR = sympy.primerange(1, 20) >>> set(PR) {2, 3, 5, 7, 11, 13, 17, 19} 到目前为止,一切顺利。但是: >>>

(Python 3.5.1)

我一直在尝试使用Sympy解决一些Project Euler问题,但是我遇到了一些奇怪的问题,关于
set(Sympy.primerange(a,b))
和类似的构造是如何工作的

>>> import sympy
>>> PR = sympy.primerange(1, 20)
>>> set(PR)
{2, 3, 5, 7, 11, 13, 17, 19}
到目前为止,一切顺利。但是:

>>> import sympy
>>> PR = sympy.primerange(1, 20)
>>> set(PR)
{2, 3, 5, 7, 11, 13, 17, 19}
>>> set(PR)
set()
简单地调用
PR
会在调用
list(PR)
一次或两次后给我
。PR中p的
也会发生同样的情况:打印(p)
列表(PR)

为什么这不起作用:

>>> import sympy, itertools
>>> sympy.sieve.extend(100)
>>> set(itertools.takewhile(lambda p: p<20, sympy.sieve))
set()
>>> sympy.sieve
<Sieve with 25 primes sieved: 2, 3, 5, ... 89, 97>
导入sympy、itertools >>>共筛延伸(100) >>>设置(itertools.takewhile(lambda p:p>>sympy.sieve
为什么我们不得到集合
{2,3,5,7,11,13,17,19}

第一个现象与生成器有关。sympy.primerange返回一个生成器,而不是一个列表。生成器允许您在元素上迭代一次,根据需要生成它们。对set()的调用迭代生成器PR中的每个元素,并使用它

itertools.takewhile的第二个参数需要一个iterable。sympy.sieve不是iterable。它允许您按索引请求任意素数,并维护一个动态内部筛选。因为sympy.sieve不是iterable,takewhile无法从中提取任何元素。这就是为什么无法获得预期结果的原因


感谢您参与Euler项目。

谢谢。这很有意义。在深入研究的过程中,我发现这会起作用:
>sympy.sieve.extend(20)>>set(sympy.sieve.\u list)
给出了
{2,3,5,7,11,13}
,并且可以多次调用。