2016-07-27 14 views
4

(Python 3.5.1)Python: set (sympy.primerange (a, b))

Ich habe versucht, Sympy für einige Projekte Euler Probleme zu verwenden, aber ich bin gekommen, über etwas seltsam, wie set(sympy.primerange(a, b)) und ähnliche Bauarbeiten.

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

So weit, so gut. Aber:

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

Aufruf einfach PR gibt mir <generator object primerange at 0x039C1720> nach zweimal list(PR) einmal oder aufrufen. Das Gleiche passiert mit for p in PR: print(p) und list(PR).

Warum funktioniert das nicht:

>>> 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> 

Warum wir die Menge {2, 3, 5, 7, 11, 13, 17, 19} nicht bekommen?

Antwort

3

Das erste Phänomen ist mit Generatoren zu tun. sympy.primerange liefert einen Generator, keine Liste. Mit Generatoren können Sie einmal über ihre Elemente iterieren und sie bei Bedarf erzeugen. Der Aufruf von set() iteriert jedes Element im Generator-PR und verbraucht es.

itertools.takewhile erfordert ein iterables für sein zweites Argument. sympy.sieve ist nicht ein iterable. Es erlaubt Ihnen, willkürliche Primzahlen durch Index anzufordern, und behält ein dynamisches inneres Sieb bei. Da sympy.sieve nicht iterierbar ist, kann takewhile keine Elemente daraus extrahieren. Deshalb erhalten Sie nicht Ihre erwarteten Ergebnisse.

Kudos zu Ihnen für das Projekt Euler.

+0

Danke. Das macht Sinn. Beim Umgraben der [Sympy API] (http://docs.sympy.org/dev/modules/ntheory.html) habe ich herausgefunden, dass das funktioniert: '>>> sympy.sieve.extend (20) >> > set (sympy.sieve._list) 'gibt' {2, 3, 5, 7, 11, 13} 'und kann mehr als einmal aufgerufen werden. –

Verwandte Themen