简体   繁体   English

使用Python中的列表推导进行推理因子分解

[英]Prime factorization using list comprehension in Python

How to write a function which returns a list of tuples like (c_i, k_i) for n such that n = c1^k1 * c2^k2 * ... , ci is a prime number. 如何编写一个函数,它返回一个元组列表,如(c_i,k_i)为n,使得n = c1 ^ k1 * c2 ^ k2 * ...,ci是素数。
For example: 12600 = 2^3 * 3^2 * 5^2 * 7^1 例如: 12600 = 2^3 * 3^2 * 5^2 * 7^1
Desired output: [(2, 3), (3, 2), (5, 2), (7, 1)] 期望的输出: [(2, 3), (3, 2), (5, 2), (7, 1)]
I know how to do it with while but is it possible to do it using list comprehension? 我知道怎么做while但是有可能使用列表理解吗? Efficiency is not required in this task. 此任务不需要效率。

# 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
    ]

I don't think this should be too hard. 我认为这不应该太难。 You don't actually need to modify n to find its prime factors, they're all completely independent of each other. 你实际上并不需要修改n来找到它的素因子,它们都完全相互独立。 So just iterate through the appropriate primes, and find the maximum power that works! 所以只需遍历适当的素数,找到有效的最大功率!

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)]

There are a few ways you might improve this further. 有几种方法可以进一步改善这一点。 You could use itertools.takewhile on an infinite generator of powers (eg itertools.count ), as once you find the first power such that prime**power is not a factor of n , none of the later ones will be either. 你可以在无限的幂itertools.count发生器上使用itertools.takewhile (例如itertools.count ),因为一旦你找到第一个幂,使得prime**power不是n的因子,后者的任何一个都不会。 That would allow you to avoid the log call. 这样可以避免log调用。

And there are a whole bunch of ways to efficiently iterate over the primes (see for instance, the very simple generator suggested here , or higher performance versions that you can find in the answers to a few different questions here on SO). 并且有很多方法可以有效地迭代质数(例如,参见此处建议的非常简单的生成器,或者您可以在SO 的几个 不同问题的答案中找到更高性能的版本)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM