如何编写一个函数,该函数返回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
]
答案 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在此处)。