# Generators/iterators, Pythonicity, and primes

Kay Schluehr kay.schluehr at gmx.net
Sun Apr 5 17:37:20 CEST 2009

```On 5 Apr., 17:14, John Posner <jjpos... at snet.net> wrote:
> Kay Schluehr said:
>
>  > g = (lambda primes = []:
>  >       (n for n in count(2) \
>  >          if
>  >              (lambda n, primes: (n in primes if primes and
> n<=primes[-1] \
>  >          else
>  >              (primes.append(n) or True \
>  >                  if all(n%p for p in primes if p <= sqrt(n)) \
>  >                  else False)))(n, primes)))()
>
> Um ... did you say "easy"? :-) This is prodigious, and it's definitely a
> solution to the generator-expression-only challenge I laid down.

That's because it is *one* expression. The avoidance of named
functions makes it look obfuscated or prodigious. Once it is properly
dissected it doesn't look that amazing anymore.

(n for n in count(2) if is_prime(n, primes))

The is_prime function has following implementation:

def is_prime(n, primes):
if primes and n<=primes[-1]:
return n in primes
else:
if all(n%p for p in primes if p <= sqrt(n)):
primes.append(n)
return True
else:
return False

But we need a lambda-fied function expression instead of the function
definition. This yields:

is_prime = lambda n, primes: (n in primes \
if primes and n<=primes[-1] \
else (primes.append(n) or True \
if all(n%p for p in primes if p <= sqrt(n)) \
else False))

Finally the trick with primes definition within an expression by means
of an optional argument in the lambda is applied.

> But I
> think this is a case in which using a generator expression causes a loss
> in "Pythonicity", rather than a gain. Many, many thanks for this!

I think so too. The solution with the simple generator expression and
the fully defined is_prime function may be just adequate.

```