I wrote a simple prime sieve (an unbounded sieve of Eratosthenes) using Python, but for some reason, it isn't working correctly. Here is the sieve:
from itertools import count
def sieve():
nums = count(2)
while True:
n = next(nums)
nums = filter(lambda k: k%n != 0, nums)
yield n
Unfortunately, this isn't working. Instead, it just returns the same values as the count(2) iterator would.
For comparison, this:
nums = count(2)
print(next(nums))
nums = filter(lambda k: k%2 != 0, nums)
print(next(nums))
nums = filter(lambda k: k%2 != 0, nums)
print(next(nums))
will print:
2
3
5
while the sieve function will print:
2 3 4
I thought the issue was with the weird behavior of Python's lambda, but replacing this line:
nums = filter(lambda k: k%n != 0, nums)
with:
def f(k): return k%n != 0
nums = filter(f, nums)
doesn't solve the issue.
Step 1: Loop through all the elements in the given range. Step 2: Check for each number if it has any factor between 1 and itself. Step 3: If yes, then the number is not prime, and it will move to the next number. Step 4: If no, it is the prime number, and the program will print it and check for the next number.
Python Program for prime numberInitialize a for loop starting from 2 ending at the integer value of the floor of the square root of the number. Check if the number is divisible by 2. Repeat till the square root of the number is checked for. In case, the number is divisible by any of the numbers, the number is not ...
num1 = input("Input a number: ") num2 = input("Input another number: ") for x in range(num1,num2): prime = True for i in range(2,x): if (x%i==0): prime = False if prime == True: print x print "Done......" It classifies 1 as a Prime Number, which is incorrect.
The problem is that the lambda
is always referring to the latest value of n
, not the one used when lambda
was created. The simplest way around it is to capture the value explicitly using a keyword argument:
from itertools import count
def sieve():
nums = count(2)
while True:
n = next(nums)
nums = filter(lambda k, n=n: k%n != 0, nums)
yield n
This Python gotcha is well-documented in various StackOverflow answers. To be fair, the same behavior is also shared by some other languages with lexical closures, such as JavaScript and Common Lisp.
It might be what you meant by "weird behavior of Python lambda" in the question, although this behavior has nothing to do with lambda
, but with what a closure really captures when referring to a mutable variable — in Python, JavaScript and Common Lisp it captures the latest value of the variable, while in Scheme it captures the value of the variable as it was at the time the closure was created.
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