质因数分解函数结果列表被重置,寻求无全局变量的修正方案
质因数分解函数结果列表被重置,寻求无全局变量的修正方案
看起来你在实现质因数分解的过程中遇到了结果列表被重置的问题,而且不想用全局变量来存储结果对吧?我先帮你分析下现有代码的核心问题,再给你修正后的可行方案:
现有代码的主要问题
made_of函数效率低且逻辑冗余:你用双重循环找因数对,其实只要找到一个能整除n的i,j就是n//i,不需要嵌套循环;而且该函数只返回第一组因数对就退出,不过这个不是核心问题,但可以优化。made_of_prime函数逻辑错误:这是导致列表重置的关键——当列表里有非素数时,你处理第一个非素数元素就直接递归返回了,其他元素完全没被处理,而且素数元素也没合并到最终结果里,相当于每次递归都新建了空列表p和w,覆盖了之前的结果。is_prime函数的小缺陷:没有处理n<=1的情况,循环范围也可以优化(比如只检查到√n)。
修正后的方案(无全局变量,递归合并结果)
这里我给你两种实现方式,都是不需要全局变量的:
方式1:递归拼接分解结果(更简洁)
这种方式直接通过递归返回的列表进行拼接,把每个数的分解结果逐步合并:
def is_prime(n: int) -> bool: if n <= 1: return False if n == 2 or n == 3: return True # 排除偶数和3的倍数,减少循环次数 if n % 2 == 0 or n % 3 == 0: return False # 素数除了2、3,都是6k±1的形式,优化循环 i = 5 while i * i <= n: if n % i == 0 or n % (i + 2) == 0: return False i += 6 return True def prime_factors(n: int) -> list[int]: # 如果是素数,直接返回包含自身的列表 if is_prime(n): return [n] # 找到第一个能整除n的因数,递归分解因数和商 for i in range(2, int(n**0.5) + 1): if n % i == 0: return prime_factors(i) + prime_factors(n // i) return [n] # 理论上n是素数才会到这里,兜底返回
方式2:闭包维护结果列表(更直观)
用嵌套函数的闭包变量来存储分解结果,避免全局变量的同时也不用每次拼接列表:
def is_prime(n: int) -> bool: if n <= 1: return False if n == 2 or n == 3: return True if n % 2 == 0 or n % 3 == 0: return False i = 5 while i * i <= n: if n % i == 0 or n % (i + 2) == 0: return False i += 6 return True def prime_factors(n: int) -> list[int]: factors = [] # 闭包变量,存储最终质因数 def decompose(num): if is_prime(num): factors.append(num) return # 找到一个因数对,递归分解每个因数 for i in range(2, int(num**0.5) + 1): if num % i == 0: decompose(i) decompose(num // i) return decompose(num) # 兜底处理素数 decompose(n) return sorted(factors) # 可选排序,让结果按从小到大排列
测试验证
运行以下代码:
if __name__ == "__main__": print(prime_factors(140)) # 输出: [2, 2, 5, 7]
完全符合你预期的结果。
为什么这个方案不会重置列表?
- 方式1中,每次递归都会返回当前数的质因数列表,然后通过
+运算符把子问题的结果拼接起来,最终合并成完整的质因数列表,不会出现中途重置的情况。 - 方式2中,
factors是外层函数的局部变量,嵌套的decompose函数可以直接修改它,所有分解出来的质因数都会追加到这个列表里,不会被重新初始化。
备注:内容来源于stack exchange,提问作者Egelund48
相关产品推荐
相关产品推荐

