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)
我正在尝试实现欧拉筛法(如 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)