2016-07-27 74 views
4

(Python的3.5.1)的Python:设置(sympy.primerange(A,B))

我一直在尝试使用Sympy一些项目欧拉的问题,但我已经遇到一些奇怪如何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给我打电话<generator object primerange at 0x039C1720>一次list(PR)两次后。 for p in PR: print(p)list(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> 

我们为什么不拿到一套{2, 3, 5, 7, 11, 13, 17, 19}

回答

3

第一个现象是与发电机有关。 sympy.primerange返回一个生成器,而不是一个列表。生成器让你迭代它们的元素一次,按需生成它们。对set()的调用遍历生成器PR中的每个元素,并将其消耗。

itertools.takewhile需要一个可迭代的第二个参数。 sympy.sieve是不是一个迭代。它允许您通过索引请求任意素数,并保持动态内部筛。由于sympy.sieve不是可迭代的,因此无法从中提取任何元素。这就是为什么你没有得到预期的结果。

对你做项目欧拉的荣誉。

+0

谢谢。这就说得通了。在[Sympy API](http://docs.sympy.org/dev/modules/ntheory.html)中挖掘,我发现这会起作用:>>> sympy.sieve.extend(20)>> > set(sympy.sieve._list)'给出'{2,3,5,7,11,13}'并且可以被多次调用。 –

相关问题