为什么我编写的Python代码无法正确返回指定数字的约数?
代码出错的核心原因
你写的约数判断逻辑本身没有问题,核心问题是在遍历列表的同时直接修改该列表的结构,这是Python循环中极其常见的新手踩坑点。
我们可以把输入12时的实际执行流程一步步拆解,就能看清问题的来源:
- 初始生成的
Divisors列表是[1,2,3,4,5,6,7,8,9,10,11,12],Python的for循环是靠内置的位置索引逐个定位要遍历的元素,每走完一次循环就会把索引值固定+1,不会因为列表内容变化自动调整位置。 - 第一次遇到不符合约数条件的元素是5:执行
Divisors.remove(5)时,不仅5被从列表里删掉,原本排在5后面的所有元素会整体往前移动一位,填补删除元素留下的空位——这时候原来在第5位(索引4)的6,会被挤到第4位(索引3)的位置,原来在第6位(索引5)的7会被挤到第5位(索引4)的位置。 - 当本次循环结束,程序按固定逻辑把索引值从4加到5,准备下一次遍历:这时候原本在索引4位置的6,就被刚好跳过了,根本不会进入后续的整除判断。
- 后面遇到7、9这类非约数元素时,会重复上面的过程:删除元素导致后续内容前移,索引自增后直接跳过当前位置剩下的元素,最终8、10这类本该被删掉的非约数,就因为被跳过硬生留在了最终输出的列表里,和你实际看到的输出完全匹配。这个问题在Python2和Python3的实现逻辑里表现完全一致,不会因为版本差异自动消失。
可直接运行的正确修复方式
- 改动最小的方案:遍历原列表的独立副本,从根源上避免遍历过程被列表修改干扰。只要把循环语句改成遍历
Divisors[:](这是Python生成列表浅拷贝的简写,和原列表内容完全一致,但是是独立的新对象),删原列表元素的操作完全不会打乱遍历的顺序:num = int(input("What number would you like to check the divisors of? ")) Divisors = list(range(1, num+1)) # 遍历列表副本,修改原列表不影响遍历节奏 for element in Divisors[:]: if num % element != 0: Divisors.remove(element) print(Divisors) - 逻辑更简洁的方案:不需要先生成全量列表再逐个删除,直接用列表推导式把满足约数条件的元素筛选出来,完全规避边遍历边修改的问题:
num = int(input("What number would you like to check the divisors of? ")) Divisors = [element for element in range(1, num+1) if num % element == 0] print(Divisors)
补充优化提示:当后续需要计算很大的数字的约数时,不需要把1到num的数全部遍历一遍,只要遍历到num的平方根就可以找到全部约数,能大幅减少循环次数提升运行效率。
内容的提问来源于stack exchange,提问作者Fandango
相关产品推荐
相关产品推荐

