python:第二次迭代时跳过 for 循环中的乘法

python: multiplication in for loop skipped on second iteration

我正在尝试实现欧拉筛法(如 programmingpraxis.com 中所述)。我的代码在第一次迭代中运行良好,但是在下一次迭代中我的乘法由于某种原因被跳过我(可能只是遗漏了一些 python-对更有经验的程序员来说是常识的行为) 我是运行这个:

import numpy as np
#set up parameters
primes = [2]
startval = 2
stopval = 10000
firstrun = True
candidates = np.arange(start=startval,stop=stopval+1,step=1)
#actual program
for idx in range(int(np.ceil(np.sqrt(stopval)))): #only up until sqrt(n) needs checking
    print('pos1')
    print(candidates)
    print(candidates[0])
    times = candidates[0]*candidates
    print(times)
    diffset = list(set(candidates)^set(times))
    if len(diffset) is not 0: #to make sure the program quits properly if diffset=[]
        primes.append(diffset.pop(0))
        print('pos2')
        print(diffset)
        candidates = diffset
        print('pos3')
        print(candidates)
    else:
        break
print(primes)

各种打印语句只是为了让我了解发生了什么。请注意,第一个输出很好,有趣的部分在第二次打印 pos1 时开始。我的候选人按照我的意愿进行了更新,新的第一个元素也是正确的。所以我的问题是:

为什么 times = candidates[0]*candidates 显然在第二次迭代时被跳过了?

请注意:我并不是要 "scratch your code, copy this working and faster, better, nicer code" 回答。那里有很多 python 实现,我想自己做。我想我在这里遗漏了一个相当重要的 python 概念,这就是为什么我的代码不运行的原因。

(有人会问:不,这不是家庭作业。我在工作场所使用了一些 python 并且喜欢在家里做这些事情以提高编码水平)

我只是 运行 你的代码。查看第 14 行中 times 的输出,您可以看到在第一次迭代后执行了操作,但不是以您想要的方式执行。 times 列表是 candidates 列表的三倍。详细说明:

第一次迭代

candidates = np.arange(start=startval,stop=stopval+1,step=1)

所以 candidates 是一个 numpy 数组。做

candidates*candidates[0]

candidates*2一样,也就是"numpy_array*number",也就是element-wise的乘法。 现在再往下

diffset = list(set(candidates) ^ set(times))
....
candidates = diffset

设置:

第二次迭代 candidates 现在是 list(见上文)。正在做

candidates*candidates[0]

只是 candidates*3,现在是 "list*number",在 python 中不是 "multiply each list element by number",而是 "create new list as being original list concatenated number times with itself"。这就是您看不到预期输出的原因。

要解决此问题,只需执行以下操作:

candidates = np.array(diffset)