0

Please, consider this Python 3 code to generate prime numbers using an unbounded sieve of eratosthenes:

import itertools
def primes():
    numbers = itertools.count(2)
    while True:
        prime = next(numbers)
        yield prime
        numbers = filter(prime.__rmod__,numbers)

prime_gen = primes()
next(prime_gen)
# Prints 2
next(prime_gen)
# Prints 3
next(prime_gen)
# Prints 5
next(prime_gen)
# Prints 7

So far so good. Now, let's replace the prime.__rmod__ function with a lambda that does the same thing:

import itertools
def primes():
    numbers = itertools.count(2)
    while True:
        prime = next(numbers)
        yield prime
        numbers = filter(lambda n: n % prime,numbers)

prime_gen = primes()
next(prime_gen)
# Prints 2
next(prime_gen)
# Prints 3
next(prime_gen)
# Prints 4
next(prime_gen)
# Prints 5

Why the lambda function is not working with the filter? There is something going on with the scope of the lambda function?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Dargor
  • 623
  • 1
  • 4
  • 12
  • 1
    yes, look at [this question](http://stackoverflow.com/questions/938429/scope-of-python-lambda-functions-and-their-parameters) for more info on why this is the case. – R Nar Nov 30 '15 at 19:10
  • Does this answer your question? [What do lambda function closures capture?](https://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture) – Karl Knechtel Aug 19 '22 at 03:49

1 Answers1

0

As R Nar comments this is due to the scope of the lambda function. Because prime is global to the lambda function the same value for prime is used in every lambda when filter tries to do its job. The solution is creating a closure for each lambda in order to make them remember the value of prime when they are created:

filter(lambda n, prime=prime: n % prime,numbers)
Dargor
  • 623
  • 1
  • 4
  • 12