关于无过滤嵌套列表推导式计算50以内非质数的逻辑疑问
理解这段找50以内非质数的Python列表推导式
嘿,咱们一步步拆解这段代码,其实它是用了埃拉托斯特尼筛法的核心思路来找出50以内的非质数(也就是合数),只是用嵌套列表推导式写得比较紧凑而已。
首先,先把这个嵌套列表推导式展开成普通的for循环,你就能一眼看明白逻辑了:
nonprime = [] # 外层循环:遍历2到7的整数(range(2,8)是左闭右开,所以i取2、3、4、5、6、7) for i in range(2, 8): # 内层循环:遍历i的所有倍数,从i*2开始,步长为i,直到小于50 for j in range(i*2, 50, i): nonprime.append(j)
接下来解释每个部分的作用:
外层循环的i为什么到7? 因为√50≈7.07,任何大于√50的合数,它的最小质因数肯定小于等于√50。比如49是7的平方,而比7大的数比如8,它的倍数已经被2的倍数覆盖了,所以只需要检查到7就足够找出50以内所有的合数。
内层循环找i的倍数:从
i*2开始(跳过i本身,因为i可能是质数),每次加i,得到的数都是i的倍数,这些数必然是合数——因为它们能被i整除,而且比i大,不可能是质数。
举个具体例子:
- 当i=2时,j会取4、6、8...48,这些都是2的倍数,全是合数;
- 当i=3时,j会取6、9、12...48,这些3的倍数也都是合数;
- 直到i=7时,j会取14、21、28...49,这些7的倍数同样是合数。
最后要注意:这段代码生成的nonprime列表会有重复元素(比如6会被i=2和i=3都添加一次),如果需要去重,可以把列表推导式改成集合推导式再转回列表:
nonprime = list({j for i in range(2, 8) for j in range(i*2, 50, i)})
内容的提问来源于stack exchange,提问作者AkshayKrish
相关产品推荐
相关产品推荐

