2016-07-27 2 views
4

(Python 3.5.1)Python: набор (sympy.primerange (а, б))

Я пытался использовать 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 is не истребитель. Он позволяет запросить произвольные простые числа по индексу и поддерживает динамическое внутреннее сито. Поскольку sympy.sieve не является итерируемым, takewhile не может извлечь из него какие-либо элементы. Вот почему вы не получите ожидаемых результатов.

Престижность вам для выполнения проекта Эйлера.

+0

Спасибо. В этом есть смысл. Выкапывая [API Sympy] (http://docs.sympy.org/dev/modules/ntheory.html), я понял, что это сработает: '>>> sympy.sieve.extend (20) >> > set (sympy.sieve._list) 'дает' {2, 3, 5, 7, 11, 13} 'и может вызываться более одного раза. –

Смежные вопросы