Idea for key parameter in all() builting, would it be feasible?
Russel Walker
russ.pobox at gmail.com
Thu Jun 20 06:05:29 EDT 2013
> If you're getting this via the mailing list, just hit Reply, and then
>
> change the To: address to python-list at python.org - that's the simplest
>
> (assuming you don't have a Reply To List feature, but you wouldn't be
>
> saying the above if you had one). That way, you get a citation line,
>
> quoted text is marked, and it's taken a minimum of effort.
I guess it was pretty late last night but I didn't notice the huge post reply button *palmface*.
> Awesome! Hey, if you *can* switch to Py3, do try to. It has heaps of
>
> improvements, and it has a future. :)
>
>
>
> ChrisA
Also I realized that aside from using map or the better alternative imap, an even better way to go might be a generator expression. Completely forgot about those.
So with a slightly less trivial example than the first
>>> all(map(lambda x: n%x, xrange(2, n)))
could be better written as
>>> all(n%x for n in xrange(2, n))
which is roughly 10 times faster and memory efficient, plus syntax is cleaner.
And roughly 1.5 times faster than imap which isn't much but prevents having to import itertools.
But I discovered a new itertools tool and my sieve was successful.
def primeset(upper):
return set([2]+range(3,upper,2)).difference(set.union(*[set(xrange(p+p,upper,p)) for p in [n for n in xrange(3,int(pow(upper, 0.5)+1)) if all(n%x for x in xrange(2, int(pow(n, 0.5)+1)))]]))
Here is the more sane version of the one-liner above.
def primeset(upper):
def isprime(n):
# brute force trial division
for d in xrange(2, int(pow(n, 0.5)+1)):
if n%d == 0: return False
return True
# Initial set of only odd numbers except for 2
numbers = set([2]+range(3, upper, 2))
# List of prime numbers up to square root of upper using brute force.
primes = [n for n in xrange(2, int(pow(upper,0.5)+1)) if isprime(n)]
# Multiples of all the prime numbers in the list above.
all_multiples = (set(xrange(p+p,upper,p)) for p in primes)
# This was allot faster than reduce(set.union, all_multiples)
multiples = set.union(*all_multiples)
# And the sieving action.
return numbers.difference(multiples)
Rough benchmarks:
>>> timer(primeset, 10**6)
1.0981476384030202
>>> # straight forward Eratosthenes sieve
>>> timer(primes, 10**6)
0.5887037628822327
More information about the Python-list
mailing list