You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手编写Python质因数提取代码运行异常:输入60结果错误、120触发ValueError

质因数计算代码运行异常排查

问题背景

作为编程入门学习者,涉及的问题或代码疏漏还请见谅。
本次编程作业要求编写代码实现:用户输入一个数字后,程序返回该数字的质因数。目前已编写的代码运行不符合预期,始终定位不到问题,更希望明确当前代码无法正常运行的原因以及修复方式,而非单纯获取更优的实现方案。

现有代码

def all_factors():
    '''first create a list of all factors'''
    number = int(input("please enter a number: ")) # ask for number
    prime_list = [] # this is gonna be the prime factor list
    check_list= list(range(2,number)) # all the numbers up to the input number. 
    factor_list = [] #all the factors of the inputnumber, including non-primes
    for factor in check_list:
        if number%factor == 0:
            factor_list.append(factor)
    
    
    ''' function to check if factor is a prime number'''

    
    prime_list = factor_list.copy()
    
    for num in prime_list: 
                
        if num%2 == 0 and num!= 2: '''remove even numbers except 2'''
            prime_list.remove(num)
            
            
        elif num%2!=0 and num!= 2:  '''remove odd numbers that are not prime '''
            try_list = list(range(2,num))
            for check in try_list:
                if num%check == 0:
                    prime_list.remove(num)
                    pass
                
    result = set(prime_list)
    print(result)
    print('the factor list is ',factor_list)
    print('the prime list is ',prime_list)

测试异常表现

分别使用60、120两个数字对代码进行测试,均出现异常:

  • 输入60时,返回结果列表中仍包含非质数的偶数
  • 输入120时程序触发报错
  • 无法理解为什么类似10这类非质数没有从prime_list中被移除

输入60的运行输出

please enter a number: 60
{2, 3, 5, 10, 15, 30}
the factor list is  [2, 3, 4, 5, 6, 10, 12, 15, 20, 30]
the prime list is  [2, 3, 5, 10, 15, 30]

输入120的报错输出

please enter a number: 120
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-19-fc97ce9d24c1> in <module>
----> 1 all_factors()

<ipython-input-16-bb4c2a026f3b> in all_factors()
     25             for check in try_list:
     26                 if num%check == 0:
---> 27                     prime_list.remove(num)
     28                     pass
     29 

ValueError: list.remove(x): x not in list

异常原因拆解

  • 核心问题1:遍历列表的同时对原列表执行删除操作。Python的列表迭代器内部按固定索引值推进,每取完一个元素就将索引值加1,不会因为列表元素的删除、移动而调整索引位置。当某个元素被删除后,后续元素会自动向前填充空位,原本在当前索引之后的元素会向前移动,导致迭代器直接跳过这些被前移的元素,从未对它们执行质数判断。
    以输入60的执行流程为例:
    1. 初始prime_list为[2,3,4,5,6,10,12,15,20,30],迭代器从索引0开始依次取元素2、3、4
    2. 取到4时执行删除操作,此时列表变为[2,3,5,6,10,12,15,20,30],原本在索引3的5前移到索引2的位置
    3. 迭代器索引自动加1走到3,取到元素6,执行删除操作,列表变为[2,3,5,10,12,15,20,30],原本在索引4的10前移到索引3的位置
    4. 迭代器索引自动加1走到4,取到元素12,执行删除操作,列表变为[2,3,5,10,15,20,30],原本在索引5的15前移到索引4的位置
    5. 迭代器索引自动加1走到5,取到元素20,执行删除操作,列表变为[2,3,5,10,15,30],原本在索引6的30前移到索引5的位置
    6. 迭代器索引自动加1走到6,已超出当前列表的最大索引5,循环直接结束
      整个流程中,前移到索引3的10、索引4的15、索引5的30从来没有被迭代器取到过,自然不会被执行质数判断和删除操作,因此最终留在列表中。
  • 核心问题2:非质数判断逻辑内重复执行删除操作,没有设置跳出机制。对于奇数非质数的判断,一旦检测到num能被try_list中的任意数整除,代码就会执行prime_list.remove(num),但这个操作写在check的遍历循环内部,没有用break跳出循环。当num被第一次删除后,后续的check判断还会继续运行,下一次再执行remove(num)时,该元素已经不在列表中,就会触发ValueError: list.remove(x): x not in list报错。
  • 附加不规范问题:代码中在判断语句行内用三引号写注释,属于写法不规范。Python中行内注释应使用#,三引号标记的内容会被当成字符串表达式执行,虽然不影响当前运行,但容易引发后续解析问题。

修复思路

  • 遍历操作和修改操作分离:先对因子列表做拷贝,遍历这个拷贝列表中的每一个元素,判断是否为质数,将符合质数要求的元素存入新的结果列表,全程不修改正在遍历的列表长度,从根源上避免跳过元素的问题。
  • 优化非质数判断逻辑:只要发现某个因子存在除1和自身外的因数,就立刻用break跳出内层判断循环,不重复执行删除操作。
  • 规范注释写法:将三引号的行内注释替换为#开头的标准注释,避免语法歧义。

内容的提问来源于stack exchange,提问作者Festi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 14:15:04