[Tutor] List comprehension question
Martin A. Brown
martin at linux-ip.net
Tue Nov 9 14:51:51 CET 2010
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)
Have a great day,
-Martin
--
Martin A. Brown
http://linux-ip.net/
More information about the Tutor
mailing list