Program poniżej [Python 3.4] jest prosty Eratosthenes sitowa:Generatory Pythona; dwa, takie same programy działają odmiennie
from itertools import *
def excl(ns,pr):
return (i for i in ns if i%pr)
def sieve(ns):
while True:
pr=next(ns)
yield pr
ns=excl(ns,pr)
# ns=(i for i in ns if i%pr)
r=list(islice(sieve(count(2)),10))
która produkuje [2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ]. OK. Odkomentowanie linii, która włącza excl() i komentowanie wywołania, daje [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Czemu?
Czy jest to związane z problemami oczekiwanymi podczas modyfikowania sekwencji wewnątrz pętli, która wykonuje iteracje?
Dziękuję za podpowiedź.
Nie jestem pewien, czy rozumiem tę odpowiedź. Prime pr nie zmienia się w excl (ani w gen.expression), zmienia się w pętli, a ten kontekst jest identyczny dla wersji inlined i "call". BTW Usunąłem błędną uwagę na temat filtra(). –
@JerzyKarczmarczuk Według [PEP 227] (https://www.python.org/dev/peps/pep-0227/), jeśli nazwa jest używana w bloku kodu (funkcja zagnieżdżona), ale nie jest tam związana i nie jest deklarowany globalnie, użycie jest traktowane ** jako odniesienie do ** najbliższego otaczającego obszaru funkcji. Jeśli chodzi o twoją sprawę, wyrażenie generatora jest funkcją pod maską i nie definiuje zmiennej "pr", więc jej 'pr' jest ** referencją ** do' pr' w funkcji otaczającej ('sito'). Co oznacza, że gdy zmienia się słowo "pr" w 'sicie', to również' pr' w wyrażeniu generatora. – ppperry