When replying, please edit your Subject line so it is more specific
than "Re: Contents of Tutor digest..."
Today's Topics:
1. Re: List comprehension question (Richard D. Moores)
2. Re: query result set (bob gailer)
3. Re: Columnar Transposition Cipher question (Stefan Behnel)
4. Re: Columnar Transposition Cipher question (Eike Welk)
5. Re: List comprehension question (Steven D'Aprano)
6. Re: Columnar Transposition Cipher question (Steven D'Aprano)
7. Re: List comprehension question (Albert-Jan Roskam)
----------------------------------------------------------------------
Message: 1
Date: Tue, 9 Nov 2010 08:17:55 -0800
From: "Richard D. Moores" <[email protected]>
To: "Martin A. Brown" <[email protected]>
Cc: [email protected]
Subject: Re: [Tutor] List comprehension question
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Tue, Nov 9, 2010 at 05:51, Martin A. Brown <[email protected]>
wrote:
Hello,
?: def proper_divisors_sum(n):
?: ? ? pd_list = []
?: ? ? for x in range(1, int(n**.5)+1):
?: ? ? ? ? if n % x == 0:
?: ? ? ? ? ? ? factor = int(x)
?: ? ? ? ? ? ? pd_list.append(factor)
?: ? ? ? ? ? ? factor2 = int(n/factor)
?: ? ? ? ? ? ? pd_list.append(factor2)
?: ? ? pd_list = list(set(pd_list))
?: ? ? pd_list.sort()
?: ? ? pd_list = pd_list[:-1]
?: ? ? return sum(pd_list)
A few questions--noting, of course, that I'm not reading this with
an eye toward performance, which it seems you are, but these occur
to me:
?* Why use a list (pd_list = []), when you want unique divisors?
? ?Why not, pd = set() ? ?Then, instead of pd_list.append(factor),
? ?pd.add(factor) or something like pd.update((factor,factor2))?
? ?(See also my suggestion below.)
?* Also, since you are throwing away the divisor n, anyway,
? ?why not skip it from the beginning? ?Like this:
? ? ?pd_list = [1,]
? ? ?for x in range(2, int(n**.5)+1):
?* So, I'm not terribly math aware, but I don't think I have
? ?substantially changed the meaning of your program. ?I find
? ?breaking out the functions makes things a bit clearer to
? ?somebody who might be reading my code later.
Combining these suggestions and splitting into separate functions
(you don't really need to sort before summing), I end up with the
below. ?Note, that I stuff the proper divisor 1 in the set at
creation time. ?This is probably not worth it from an optimization
perspective, but as I have learned, the only way to know is to
time
it (and I didn't time it).
? ? ?def proper_divisors_sum(n):
? ? ? ? ?return sum(proper_divisors(n))
? ? ?def proper_divisors_sorted(n):
? ? ? ? ?return sorted(proper_divisors(n))
? ? ?def proper_divisors(n):
? ? ? ? ?pd = set((1,))
? ? ? ? ?for x in range(2, int(n**.5)+1):
? ? ? ? ? ? ?factor, mod = divmod(n,x)
? ? ? ? ? ? ?if mod == 0:
? ? ? ? ? ? ? ? ?pd.update((x,factor))
? ? ? ? ?return list(pd)
Thanks for your ideas, Martin. I adopted your idea of starting at
2,
with an initial list of [1]. It resulted in a small increase in
speed. And you're right, I don't need to sort.
Speed is important, because the function is the heart of my amiable
numbers script. Did you happen to see that post of mine?
#Here's my fastest version before seeing Martin's post:
def proper_divisors_sum1(n):
pd_list = []
for x in range(1, int(n**.5)+1):
if n % x == 0:
pd_list.append(x)
pd_list.append(n//x)
pd_list = list(set(pd_list))
pd_list.sort()
pd_list = pd_list[:-1]
return sum(pd_list)
#This uses several of Martin's ideas
# It's now my fastest version
def proper_divisors_sum2(n):
pd = set((1,))
for x in range(2, int(n**.5)+1):
if n % x == 0:
pd.update((x, n//x))
return sum(list(pd))
Here's what I put together from all your points, except for the
splitting off of several small functions:
# This incorporates all of Martin's ideas
# Seems that divmod() is a speed killer
def proper_divisors_sum3(n):
pd = set((1,))
for x in range(2, int(n**.5)+1):
factor, mod = divmod(n,x)
if mod == 0:
pd.update((x,factor))
return sum(list(pd))
It may be that I've haven't done your suggestions justice, but that
function is 76% slower than proper_divisors_sum2().
See <http://tutoree7.pastebin.com/R82876Eg> for a speed test with n
=
100,000 and 100,000 loops
Thanks again, Martin.
Dick
------------------------------
Message: 2
Date: Tue, 09 Nov 2010 12:00:56 -0500
From: bob gailer <[email protected]>
To: [email protected]
Subject: Re: [Tutor] query result set
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
When starting a new subject, please start with a new email. Do not
"hijack" an existing one, as that causes your query to appear as
part of
the hijacked thread.
--
Bob Gailer
919-636-4239
Chapel Hill NC
------------------------------
Message: 3
Date: Tue, 09 Nov 2010 18:36:43 +0100
From: Stefan Behnel <[email protected]>
To: [email protected]
Subject: Re: [Tutor] Columnar Transposition Cipher question
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed
Steven D'Aprano, 09.11.2010 05:01:
http://pypi.python.org/pypi/obfuscate
Hmm - why is the Windows installer on that page called
"linux-i686"?
Stefan
------------------------------
Message: 4
Date: Tue, 9 Nov 2010 19:37:28 +0100
From: Eike Welk <[email protected]>
To: [email protected]
Subject: Re: [Tutor] Columnar Transposition Cipher question
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Tuesday 09.11.2010 18:36:43 Stefan Behnel wrote:
Steven D'Aprano, 09.11.2010 05:01:
> http://pypi.python.org/pypi/obfuscate
Hmm - why is the Windows installer on that page called
"linux-i686"?
It was probably created on Linux. Python's Distutils create
installers for
Windows even on Linux. They get file names that contain "linux-".
You must
rename them, otherwise your users get confused.
I did never try them, because I have no Windows computer. Do these
Windows
installers work when they are created on Linux?
Eike.
------------------------------
Message: 5
Date: Wed, 10 Nov 2010 07:54:24 +1100
From: Steven D'Aprano <[email protected]>
To: [email protected]
Subject: Re: [Tutor] List comprehension question
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed
Richard D. Moores wrote:
See <http://tutoree7.pastebin.com/R82876Eg> for a speed test with
n =
100,000 and 100,000 loops
As a general rule, you shouldn't try to roll your own speed tests.
There
are various subtleties that can throw your results right out.
Timing
small code snippets on modern multi-tasking computers is fraught
with
difficulties.
Fortunately Python comes with that battery already included: the
timeit
module. You can use it from the shell like this:
python -m timeit -s "setup code goes here" "test code goes here"
At the Python interactive interpreter, the most useful pattern I've
found is:
from timeit import Timer
t = Timer("proper_divisors(n)",
"from __main__ import proper_divisors; n = 100000")
min(t.repeat(repeat=5, number=100000))
Or if you're happy with Python's defaults, that last line can be
just:
min(t.repeat())
--
Steven
------------------------------
Message: 6
Date: Wed, 10 Nov 2010 08:29:51 +1100
From: Steven D'Aprano <[email protected]>
To: [email protected]
Subject: Re: [Tutor] Columnar Transposition Cipher question
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Eike Welk wrote:
On Tuesday 09.11.2010 18:36:43 Stefan Behnel wrote:
Steven D'Aprano, 09.11.2010 05:01:
http://pypi.python.org/pypi/obfuscate
Hmm - why is the Windows installer on that page called
"linux-i686"?
It was probably created on Linux.
That would be it.
> Python's Distutils create installers for
Windows even on Linux. They get file names that contain "linux-".
You must
rename them, otherwise your users get confused.
I didn't realise that.
I did never try them, because I have no Windows computer. Do these
Windows
installers work when they are created on Linux?
I'm pretty sure I tried it, once, but I might be confabulating.
--
Steven
------------------------------
Message: 7
Date: Tue, 9 Nov 2010 13:58:22 -0800 (PST)
From: Albert-Jan Roskam <[email protected]>
To: Steven D'Aprano <[email protected]>, [email protected]
Subject: Re: [Tutor] List comprehension question
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
For larger blocks of code, cProfile may also be useful for speed
tests.
Cheers!!
Albert-Jan
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All right, but apart from the sanitation, the medicine, education,
wine,
public
order, irrigation, roads, a fresh water system, and public health,
what have
the
Romans ever done for us?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
________________________________
From: Steven D'Aprano <[email protected]>
To: [email protected]
Sent: Tue, November 9, 2010 9:54:24 PM
Subject: Re: [Tutor] List comprehension question
Richard D. Moores wrote:
See <http://tutoree7.pastebin.com/R82876Eg> for a speed test with
n =
100,000 and 100,000 loops
As a general rule, you shouldn't try to roll your own speed tests.
There are
various subtleties that can throw your results right out. Timing
small code
snippets on modern multi-tasking computers is fraught with
difficulties.
Fortunately Python comes with that battery already included: the
timeit
module.
You can use it from the shell like this:
python -m timeit -s "setup code goes here" "test code goes here"
At the Python interactive interpreter, the most useful pattern I've
found
is:
from timeit import Timer
t = Timer("proper_divisors(n)",
"from __main__ import proper_divisors; n = 100000")
min(t.repeat(repeat=5, number=100000))
Or if you're happy with Python's defaults, that last line can be
just:
min(t.repeat())
-- Steven
_______________________________________________
Tutor maillist - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.python.org/pipermail/tutor/attachments/20101109/a28a4a73/attachment.html>
------------------------------
_______________________________________________
Tutor maillist - [email protected]
http://mail.python.org/mailman/listinfo/tutor
End of Tutor Digest, Vol 81, Issue 39
*************************************