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.
Start with:
(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.
More information about the Python-list
mailing list