Here's a simpler program that illustrates the same problem.
adders = [] for i in range(4): adders.append(lambda a: i + a) print(adders[0](3))
While you can expect the output to be 3 , the actual output will be 6 . This is because closing in python remembers the name and scope of the variable, not the value when the lambda was created. Since i was changed at the time of using lambda, lambda uses the last value of i .
The same thing happens in your function. Whenever n changes, all lambda functions in different filters also change. Thus, by the time the iterator reaches 9 , all filters are filtering factors 7 , not 5 or 3 .
Since in your first approach you create a new scope with every call to _not_divisible , the function works as intended.
If you absolutely must use lambda directly, you can use the second argument as follows:
def primes(): yield 2 L=_odd_iter() while True: n=next(L) yield n L=filter(lambda x, n=n: x%n>0, L)
merlyn
source share