(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()
在{em>或两次致电PR
后,只需拨打<generator object primerange at 0x039C1720>
即可{@ 1}}。 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>
?
答案 0 :(得分:3)
第一个现象是与发电机有关。 sympy.primerange返回生成器,而不是列表。生成器允许您迭代它们的元素一次,按需生成它们。对set()的调用遍历生成器PR中的每个元素,消耗它。
itertools.takewhile需要一个可迭代的第二个参数。 sympy.sieve 不可迭代。它允许您通过索引请求任意素数,并维护一个动态内部筛子。因为sympy.sieve不是可迭代的,所以不能从中提取任何元素。这就是为什么你没有得到预期的结果。
赞赏你做Project Euler。