The program below [Python 3.4] is a simple Eratosthenes sieve:
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))
which produces [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]. OK. Uncommenting the line which inlines excl(), and commenting the call, gives [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Why?
Is it related to troubles expected when modyfing a sequence inside a loop which iterates over it?
Thank you for any hint.
Generators allow you to create iterators in a very pythonic manner. Iterators allow lazy evaluation, only generating the next element of an iterable object when requested. This is useful for very large data sets. Iterators and generators can only be iterated over once.
A Python generator is a function that produces a sequence of results. It works by maintaining its local state, so that the function can resume again exactly where it left off when called subsequent times. Thus, you can think of a generator as something like a powerful iterator.
Key takeaways: motivation and uses behind generators Generators are memory efficient since they only require memory for the one value they yield. Generators are lazy: they only yield values when explicitly asked. You can feed the output of a generator to the input of another generator to form data pipelines.
Generators help us with memory efficiency. They help with time efficiency. They act like iterators. So we don't need to implement our own iterators from scratch.
Your problem is that the pr
referred to by the generator expression is the same pr
that you modify in the next iteration of your while loop, so every number that is not divisible by the previous 'prime' number is treated as 'prime'. Which itself modifies pr
and so in. In the excl
function, the pr
that you refer to is the one passed as an argument, which never changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With