A more pythonish code

nn pruebauno at latinmail.com
Thu Feb 25 11:11:09 EST 2010



prasad_chand wrote:
> Hi,
>
> I use python to do simple math problems as a hobby.
>
> I have made a program that finds the number of divisors(factors) of a
> given number. I am hoping to improve my language skills, specifically
> I would like to re-write the function "prime_factors" more gracefully.
> While the program works right, I am hoping that I could get some input
> on how to write better python code. I have attached the code below.
>
>
> def prime_factors(n):
>     """
>     Reduce a number to its prime factors. e.g. 48 is 2^4,3^1 (add (4+1)
> (1+1) = 10)
>
>     Updates a global dictionary(my_dict) with prime numbers and number
> of occurances. In the case of 48 {2:4,3:1}
>
>     """
>     tmp_n = n
>
>     while True:
>
>         if tmp_n == 1:
>             break
>
>         tmp_check = tmp_n
>
>         for x in range(2,int(ceil(sqrt(tmp_n)) + 1)):
>             if tmp_n % x == 0:
>                 add_to_dict(x)
>                 tmp_n /= x
>                 break
>
>         if tmp_check == tmp_n: #number is prime...so just to add to
> dict
>             add_to_dict(tmp_n)
>             break
>
>
> def add_one(x):
>     return x+1
>
>
> def mul(x,y):
>     return x * y
>
> def add_to_dict(p_num):
>     if my_dict.has_key(p_num):
>         my_dict[p_num] += 1
>     else:
>         my_dict[p_num] = 1
>
>
> my_dict = {}
>
>
> prime_factors(135)
> l = map(add_one,my_dict.values())
> print reduce(mul, l, 1)
>
>
> Thanks for your time.

I did a quick refactoring for Python 3.1 (should mostly work in older
versions too):

from math import ceil, sqrt
from functools import reduce
from collections import defaultdict
from operator import mul

def prime_factors(n):
    """
    Reduce a number to its prime factors. e.g. 48 is 2^4,3^1 (add
(4+1)
    (1+1) = 10)
    """
    factors = defaultdict(int)
    while n != 1:
        for x in range(2,int(ceil(sqrt(n)) + 1)):
            if n % x == 0:
                factors[x] += 1
                n /= x
                break
        else:
            #number is prime...so just to add to dict
            factors[int(n)] += 1
            break
    return factors

factors = prime_factors(135)
exponents = [x+1 for x in factors.values()]
print(reduce(mul, exponents, 1))




More information about the Python-list mailing list