我有一个数字素因数的 Python 列表。我如何(Python方式)找到所有因素?
我正在研究一个欧拉项目问题,该问题需要对整数进行因式分解。我可以列出作为给定数字的因子的所有素数。算术基本定理意味着我可以使用这个列表来导出该数字的每个因数。
我当前的计划是获取基本素数列表中的每个数字并提高其幂,直到它不再是整数因子,以找到每个素数的最大指数。然后,我将乘以素数指数对的每种可能的组合。
例如,对于 180:
Given: prime factors of 180: [2, 3, 5]
Find maximum exponent of each factor:
180 / 2^1 = 90
180 / 2^2 = 45
180 / 2^3 = 22.5 - not an integer, so 2 is the maximum exponent of 2.
180 / 3^1 = 60
180 / 3^2 = 20
180 / 3^3 = 6.6 - not an integer, so 2 is the maximum exponent of 3.
180 / 5^1 = 36
180 / 5^2 = 7.2 - not an integer, so 1 is the maximum exponent of 5.
接下来,将这些组合进行最大指数以获得因子:
2^0 * 3^0 * 5^0 = 1
2^1 * 3^0 * 5^0 = 2
2^2 * 3^0 * 5^0 = 4
2^0 * 3^1 * 5^0 = 3
2^1 * 3^1 * 5^0 = 6
2^2 * 3^1 * 5^0 = 12
2^0 * 3^2 * 5^0 = 9
2^1 * 3^2 * 5^0 = 18
2^2 * 3^2 * 5^0 = 36
2^0 * 3^0 * 5^1 = 5
2^1 * 3^0 * 5^1 = 10
2^2 * 3^0 * 5^1 = 20
2^0 * 3^1 * 5^1 = 15
2^1 * 3^1 * 5^1 = 30
2^2 * 3^1 * 5^1 = 60
2^0 * 3^2 * 5^1 = 45
2^1 * 3^2 * 5^1 = 90
2^2 * 3^2 * 5^1 = 180
因此因子列表 = [1, 2, 3, 4, 5, 6, 9, 10, 12, 15 , 18, 20, 30, 36, 45, 60, 90, 180]
这是我到目前为止的代码。有两个问题:首先,我认为它一点也不Pythonic。我想解决这个问题。其次,我真的没有 Pythonic 方法来执行组合第二步。出于羞耻,我让你免受这组荒谬的循环的困扰。
n 是我们要分解的数字。 listOfAllPrimes 是预先计算的素数列表,最多 1000 万个。
def getListOfFactors(n, listOfAllPrimes):
maxFactor = int(math.sqrt(n)) + 1
eligiblePrimes = filter(lambda x: x <= maxFactor, listOfAllPrimes)
listOfBasePrimes = filter(lambda x: n % x ==0, eligiblePrimes)
listOfExponents = [] #(do I have to do this?)
for x in listOfBasePrimes:
y = 1
while (x**(y+1)) % n == 0:
y += 1
listOfExponents.append(y)
I'm working on a Project Euler problem which requires factorization of an integer. I can come up with a list of all of the primes that are the factor of a given number. The Fundamental Theorem of Arithmetic implies that I can use this list to derive every factor of the number.
My current plan is to take each number in the list of base primes and raise its power until it is no longer an integer factor to find the maximum exponents for each prime. Then, I will multiply every possible combination of prime-exponent pairs.
So for example, for 180:
Given: prime factors of 180: [2, 3, 5]
Find maximum exponent of each factor:
180 / 2^1 = 90
180 / 2^2 = 45
180 / 2^3 = 22.5 - not an integer, so 2 is the maximum exponent of 2.
180 / 3^1 = 60
180 / 3^2 = 20
180 / 3^3 = 6.6 - not an integer, so 2 is the maximum exponent of 3.
180 / 5^1 = 36
180 / 5^2 = 7.2 - not an integer, so 1 is the maximum exponent of 5.
Next, do every combination of these up to the maximum exponent to get the factors:
2^0 * 3^0 * 5^0 = 1
2^1 * 3^0 * 5^0 = 2
2^2 * 3^0 * 5^0 = 4
2^0 * 3^1 * 5^0 = 3
2^1 * 3^1 * 5^0 = 6
2^2 * 3^1 * 5^0 = 12
2^0 * 3^2 * 5^0 = 9
2^1 * 3^2 * 5^0 = 18
2^2 * 3^2 * 5^0 = 36
2^0 * 3^0 * 5^1 = 5
2^1 * 3^0 * 5^1 = 10
2^2 * 3^0 * 5^1 = 20
2^0 * 3^1 * 5^1 = 15
2^1 * 3^1 * 5^1 = 30
2^2 * 3^1 * 5^1 = 60
2^0 * 3^2 * 5^1 = 45
2^1 * 3^2 * 5^1 = 90
2^2 * 3^2 * 5^1 = 180
So the list of factors = [1, 2, 3, 4, 5, 6, 9, 10, 12, 15, 18, 20, 30, 36, 45, 60, 90, 180]
Here is the code I have so far. Two problems: First, I don't think it is very Pythonic at all. I'd like to fix that. Second, I really don't have a Pythonic way to do the combinatoric second step. Out of shame, I've spared you from the ridiculous set of loops.
n is the number we want to factor. listOfAllPrimes is a precalculated list of the primes up to 10 million.
def getListOfFactors(n, listOfAllPrimes):
maxFactor = int(math.sqrt(n)) + 1
eligiblePrimes = filter(lambda x: x <= maxFactor, listOfAllPrimes)
listOfBasePrimes = filter(lambda x: n % x ==0, eligiblePrimes)
listOfExponents = [] #(do I have to do this?)
for x in listOfBasePrimes:
y = 1
while (x**(y+1)) % n == 0:
y += 1
listOfExponents.append(y)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
考虑简单地重复每个质因数,而不是指数列表,因为它是的次数。之后,处理生成的
primefactors
list-with-repetitions,itertools.combinations 正是您所需要的 - 您只需要包含长度 2 到 len(primefactors) - 1 项的组合(只有一个的组合是质因数,所有这些都将是原始数字 - 如果您也想要这些,只需使用range(1, len(primefactors) + 1)
而不是range(2 , len(primefactors))
我的主要建议将使用)。结果中将会出现重复(例如,
6
将作为12
的因子出现两次,因为后者的primefactors
将是[2, 2, 3]
)并且它们当然可以通过通常的方式被淘汰(例如sorted(set(results))
)。要计算给定
listOfAllPrimes
的primefactors
,请考虑以下示例:Instead of a list of exponents, consider simply repeating each prime factor by the number of times it is a factor. After that, working on the resulting
primefactors
list-with-repetitions, itertools.combinations does just what you need -- you'll just require the combinations of length 2 tolen(primefactors) - 1
items included (the combinations of just one are the prime factors, that of all of them will be the original number -- if you want those too, just userange(1, len(primefactors) + 1)
instead of therange(2, len(primefactors))
which my main suggestion would use).There will be repetitions in the results (e.g.,
6
will appear twice as a factor of12
, since the latter'sprimefactors
will be[2, 2, 3]
) and they can of course be weeded out in the usual ways (i.e.sorted(set(results))
for example).To compute
primefactors
givenlistOfAllPrimes
, consider for example:为什么你要从一组素因数开始你的解决方案?当你对一个数字进行因式分解时,你可以很容易地得到它的所有质因数(重复的),并从中得到每个因数的指数。考虑到这一点,你可以这样写:
get_prime_factors
和product
这里没有实现,但你明白了(两者都写起来很简单)恕我直言,是数学问题,欧拉问题可以使用函数式而不是命令式很好地解决(尽管我承认某些解决方案可能不会像期望的那样像 pythonic 那样出现)。
Why do you begin your solution from the set of prime factors? when you factorize a number you can as easily get all its prime factors (repeated) and from them the exponents for each factor. With this in mind, you can write this:
get_prime_factors
andproduct
are not implemented here, but you get the idea (both are pretty simple to write)IMHO, being mathematic problems, the Euler problems can be nicely solved using functional instead of imperative style (though I acknowledge that some solutions may not come out as pythonic as desired).
您可以使用
itertools.combinations()
一旦获得重复素数列表,即可获得所有可能的因子组合,例如180
的[2, 2, 3, 3, 5]
。然后,只需将每个组合的分量相乘即可得到一个因子。You could use
itertools.combinations()
to get all possible combinations of factors once you've gotten your list of repeated-primes, such as[2, 2, 3, 3, 5]
for180
. Then, simply multiplying the components from each combination will get you a factor.有一些更酷的 Python 功能:
With a few cooler Python features:
这是原始问题的简单有效的解决方案:
输出列表未排序。如果你愿意,你可以让它变得更加“Pythonic”,无论这意味着什么。
Here's a simple and efficient solution to the original problem:
The output list is unsorted. You can make it more "pythonic" if you want, whatever that means.
多合一解决方案;即不需要现有的主要因素列表。
注意[1]:作为质数生成器,您可以从如何实现高效的无限生成器中选择一个Python 中的质数? 或使用您自己的(例如您的
listOfAllPrimes
)。这会生成一个完整的因子列表,即包括
1
和number
参数本身。如果您想省略这些,可以使用all_factors(number)[1:-1]
。An all in one solution; i.e. no need for an existing list of the prime factors.
Note[1]: As a prime number generator, you can choose one from How to implement an efficient infinite generator of prime numbers in Python? or use your own (e.g. your
listOfAllPrimes
).This produces a full factor list, i.e. including
1
and thenumber
argument itself. If you want to omit these, you can useall_factors(number)[1:-1]
.