2016-07-27 5 views
4

(Pythonの3.5.1)パイソン:セット(sympy.primerange(b)参照)

私はいくつかのプロジェクトオイラーの問題をSympyを使用しようとしてきたが、私は方法についての奇妙な何かに遭遇しましたset(sympy.primerange(a, b))および同様の構成が機能する。

>>> import sympy 
>>> PR = sympy.primerange(1, 20) 
>>> set(PR) 
{2, 3, 5, 7, 11, 13, 17, 19} 

これまでのところ、とても良いです。しかし:単にPRを呼び出す

>>> import sympy 
>>> PR = sympy.primerange(1, 20) 
>>> set(PR) 
{2, 3, 5, 7, 11, 13, 17, 19} 
>>> set(PR) 
set() 

は二回またはたらlist(PR)を呼び出した後、私に<generator object primerange at 0x039C1720>を与えます。同じことが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

第1の現象は、発電機を使用することである。 sympy.primerangeはリストではなくジェネレータを返します。ジェネレータを使用すると、それらの要素を一度反復して、要求に応じて生成することができます。 set()を呼び出すと、ジェネレータPRのすべての要素が繰り返し消費されます。

itertools.takewhileには、2番目の引数にiterableが必要です。 sympy.sieveはではなく、です。それは、インデックスによって任意の素数を要求することができ、動的な内部ふるいを維持します。 sympy.sieveは反復可能ではないので、takewhileはそこから要素を抽出することはできません。そういうわけで、期待した結果が得られないのです。

プロジェクトオイラーをしてくださったことを誇りに思います。

+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} 'を与え、複数回呼び出すことができます。 –

関連する問題