Thanks, but first one not working!!!
On 11/10/10, [email protected] <[email protected]> wrote: > Send Tutor mailing list submissions to > [email protected] > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > [email protected] > > You can reach the person managing the list at > [email protected] > > 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 > ************************************* > _______________________________________________ Tutor maillist - [email protected] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
