[Python-ideas] Is this PEP-able? for X in ListY while conditionZ:
Andrew Barnert
abarnert at yahoo.com
Mon Jul 1 19:17:29 CEST 2013
On Jul 1, 2013, at 4:57, Oscar Benjamin <oscar.j.benjamin at gmail.com> wrote:
> This algorithm is actually even poorer as it doesn't stop at sqrt(n).
> We can fix that with takewhile:
>
> from itertools import count, takewhile
>
> def primes():
> primes_seen = []
> for n in count(2):
> if all(n % p for p in takewhile(lambda p: p**2 < n, primes_seen)):
> yield n
> primes_seen.append(n)
>
> primes100 = {p for p in takewhile(lambda p: p < 100, primes()}
>
> Using for/while this becomes significantly clearer (in my opinion):
>
> from itertools import count
>
> def primes():
> primes_seen = []
> for n in count(2):
> if all(n % p for p in primes_seen while p**2 <= n):
> yield n
> primes_seen.append(n)
>
> primes100 = {p for p in primes() while p < 100}
There are already ways to improve the readability of that line:
candidates = takewhile(lambda p: p**2 < n, primes_seen)
if all(n % p for p in candidates):
Or, better:
def candidate(p): return p**2 < n
if all(n % p for p in takewhile(candidate, primes_seen)):
Yes, this means splitting the line in two just so you can avoid lambda, and it's exactly parallel to the case for if clauses vs. filter. I think the benefit to all of these solutions is pretty firmly established by this point.
But, as Nick pointed out earlier, there's probably a reason that filter is a builtin and takewhile is not. It's not _as much_ benefit. And meanwhile, the cost is higher because there's no familiar, pre-existing syntax to borrow.
I'll grant that it's entirely possible that the problem is just that I'm much more familiar with while statements than with for...while statements for historical reason, and after a bit of exposure the problem will go away (like ternary statements, which everyone gets pretty quickly, as opposed to for...else, which many stay confused by). But still, we can't expect that python programmers will ever be as familiar with for...while as they are with if (which works the same as in almost every other language, is one of the first constructs every novice is taught, etc.).
More information about the Python-ideas
mailing list