我正在研究涉及素数因子分解的问题,并且遇到了关于列表理解的问题。
我有一个数字的素数因子列表,当然列表可以是任意数量的数字。它可能是[2,3,5]或只是[2],或[2,3,11,17]等。
我希望能够找到所有这些数字的产品,使产品小于或等于100,000。因此,例如,如果我的素因子化是[2,3,5],我想得到自然数a,b,c的所有数字形式(2 ^ a)(3 ^ b)(5 ^ c),满足(2 ^ a)(3 ^ b)(5 ^ c)< = 100,000。
如果素数因子的数量是任意长度,有没有办法用列表理解来做到这一点?
答案 0 :(得分:1)
您可以使用递归函数来选择其中一个因子并将当前总数乘以直到总数高于限制。对于每次迭代,您可以在移动到下一个因子的同时递归调用相同的函数。一旦你筋疲力尽所有因素,只需产生当前总数:
def prods(factors, limit, index = 0, total = 1):
# Base case, yield current number
if index >= len(factors):
yield total
return
while total <= limit:
# Python 3 yield from could be used
for res in prods(factors, limit, index + 1, total):
yield res
total *= factors[index]
print list(prods([2, 3, 5], 100))
输出:
[1, 5, 25, 3, 15, 75, 9, 45, 27, 81, 2, 10, 50, 6, 30, 18, 90, 54, 4, 20, 100, 12, 60, 36, 8, 40, 24, 72, 16, 80, 48, 32, 96, 64]
答案 1 :(得分:0)
检查一下。
import math
Nmax = 100
primeLst = [2, 3, 5]
result = []
enumMax = [int(math.floor(math.log(Nmax) / math.log(i))) for i in primeLst]
def prod(i, curRes):
if curRes > Nmax:
return
if i==len(primeLst):
result.append(curRes)
else:
for j in range(enumMax[i]+1):
prod(i+1, curRes * (primeLst[i]**j))
prod(0, 1)
# result: [1, 5, 25, 3, 15, 75, 9, 45, 27, 81, 2, 10, 50, 6, 30, 18, 90, 54, 4, 20, 100, 12, 60, 36, 8, 40, 24, 72, 16, 80, 48, 32, 96, 64]
答案 2 :(得分:0)
@ niemmi的答案修改使用heapq.merge
合并每个递归调用的每个序列,以按递增顺序生成产品:
from heapq import merge
def prods(factors, limit, index = 0, total = 1):
# Base case, yield current number
if index >= len(factors):
yield total
return
iters = []
while total < limit:
iters.append(prods(factors, limit, index + 1, total))
total *= factors[index]
for res in merge(*iters):
yield res
print list(prods([2, 3, 5], 100))
有输出:
>>> print list(prods([2, 3, 5], 100))
[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96]