使用Python中的列表理解进行素数分解

时间:2018-10-29 13:14:31

标签: python python-3.x list-comprehension factorization

如何编写一个函数,该函数返回n的(c_i,k_i)元组列表,使得n = c1 ^ k1 * c2 ^ k2 * ...,ci是素数。
例如:12600 = 2^3 * 3^2 * 5^2 * 7^1
所需的输出:[(2, 3), (3, 2), (5, 2), (7, 1)]
我知道如何使用while来做到这一点,但是是否可以使用列表理解来做到这一点?该任务不需要效率。

# naive function 
def is_prime(n):
    return n > 1 and all(n % i != 0 for i in range(2, n))

# while version
def factorization_while(n):
    res = []
    for i in range(1, n + 1):
        if is_prime(i):
            j = 0
            while n % i == 0:
                n = n // i
                j += 1
            if j != 0:
                res.append((i, j))
    return res

# list comprehension version
def factorization(n):
    return [
        (i, j) for i in range(1, n + 1) if is_prime(i) \
        and n % i == 0 ... # add smth
    ]

1 个答案:

答案 0 :(得分:3)

我不认为这应该太难了。实际上,您无需修改​​n即可找到其主要因素,它们完全相互独立。因此,只需遍历适当的素数,并找到起作用的最大功率即可!

from math import log

def prime_factors(n):
    return [(prime, max(power for power in range(1, int(log(n, prime))+1)
                              if n % prime**power == 0))
            for prime in range(2, n+1) if n % prime == 0 and isprime(prime)]

有几种方法可以进一步改善这一点。您可以在无穷大的幂生成器(例如itertools.takewhile)上使用itertools.count,因为一旦找到第一个幂使得prime**power不是n的因数,就不会以后的要么是。这样可以避免进行log调用。

有很多方法可以有效地遍历素数(例如,参见建议使用非常简单的生成器here或在a few的答案中可以找到更高性能的版本different questions在此处)。