Setting a limit on an infinite generator in Python

I am trying to make the generator below to set an upper limit for the returned numbers.

The call list(it.takewhile(lambda x: x < 100, get_primes()))returns a list of all primes up to 100, as expected, but list(get_primes(100))(which should return the same list in the same way) just returns with an empty list.

Obviously, I could include if n and candidate>=n: breakin a loop for, but what interests me most is why the design if n: returndoes not work as I expect. Shouldn't he return the same tester takewhilethat works above? What am I not seeing here?

import itertools as it

def get_primes(n=None):
    """
    Generates primes to a max of n.

    >>> list(get_primes(100))
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
    """
    if n:
        return it.takewhile(lambda x: x < n, get_primes())
    composites = {}
    yield 2
    for candidate in it.count(3, 2):
        prime_factor = composites.pop(candidate, None)
        if prime_factor is None:
            yield candidate
            composites[candidate**2] = candidate
        else:
            composite = candidate + 2*prime_factor
            while composite in composites:
                composite += 2*prime_factor
            composites[composite] = prime_factor
+4
source share
2 answers

Here:

return it.takewhile(lambda x: x < n, get_primes())

, return yield. Python yield from.

: Python 3.3

+3

return it.takewhile(lambda x: x < n, get_primes())

, - StopIteration().

#return all the values from generator
for a in it.takewhile(lambda x: x < n, get_primes())
    yield a

return 
+2

All Articles