运行此python脚本时出错。
def thousandthPrime():
count=0
candidate=5 #candidates for prime no. these are all odd no.s Since starts at 5 therefore we find 998th prime no. as 2 and 3 are already prime no.s
while(True):
#print 'Checking =',candidate
for i in range(2,candidate/2): #if any number from 2 to candidate/2 can divide candidate with remainder = 0 then candidate is not a prime no.
if(candidate%i==0):
break
if i==(candidate/2)-1: # If none divide it perfectly, i will reach candidate/2-1 eventually. So, this is a prime number.
count+=1
print 'No. of prime no.s found excluding 2 and 3 =',count, '--->',candidate
if(count==998):
print 'The thousandth prime is',candidate
break
candidate+=2 # to go to the next odd number.
我收到此错误:
File "/home/.../xxx.py", line 19, in thousandthPrime
if i==(candidate/2)-1: # If none divide it perfectly, i will reach candidate/2-1 eventually. So, this is a prime number.
UnboundLocalError: local variable 'i' referenced before assignment
但是如果我替换候选人/ 2只是候选人,我没有错误,虽然它会增加一些不必要的计算。
答案 0 :(得分:6)
您将candidate
声明为整数。因此candidate/2
也是一个整数,特别是2.然后,range(2, candidate/2)
为range(2, 2)
,这是什么都没有,所以i
永远不会被初始化。您需要设置candidate=5.0
以使其成为一个浮点数并且一切都应该很好。
修改强>
正如评论中指出的那样,简单地重新定义candidate
会给你一个类型错误,但它应该足以让你走上正轨。注意,range(x, y)
需要整数,您可能需要在使用int()
进行除法或限制计算后再次转换为整数。此外,您可能想要了解为什么math.sqrt
函数被提及与素性测试相关
答案 1 :(得分:0)
如果您单步执行,问题很简单:
>>> candidate=5
>>> candidate/2
2
>>> range(2, 2)
[]
>>> for i in []: print(i)
>>> i
NameError: name 'i' is not defined
你的循环是空的,所以你永远不会介入它,所以永远不会定义i
。
正如其他地方的评论中指出的那样,您实际上只需要检查int(sqrt(candidate))
,而不是candidate/2
。但如果你这样做,你仍然会遇到同样的问题:int(sqrt(5))
仍然是2
。
这意味着这个测试:
if i==(candidate/2)-1:
...正在尝试访问尚未定义的变量。
但如果你退一步思考一下你真正在测试什么,那就是伪代码,就是这样:
if I finished the loop without break:
Python有一种内置的方式可以说:循环上的else
子句。
事实上,介绍此功能的教程部分break
and continue
Statements, and else
Clauses on Loops有一个与您的非常相似的示例:
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
如果在没有else
的情况下完成循环,将执行break
子句 - 其中包括循环迭代器为空的情况。
所以,在你的代码中:
while(True):
#print 'Checking =',candidate
for i in range(2,candidate/2): #if any number from 2 to candidate/2 can divide candidate with remainder = 0 then candidate is not a prime no.
if(candidate%i==0):
break
else: # If none divide it perfectly, i will reach candidate/2-1 eventually. So, this is a prime number.
count+=1
print 'No. of prime no.s found excluding 2 and 3 =',count, '--->',candidate
答案 2 :(得分:-1)
这个代码中没有问题,即使在预期范围之外使用变量i
(在for
构造内部)也没有问题,我应该在完成for循环后保持定义,提供...
...对于某些变量,for循环至少应运行声明名称i
。
由于没有发生这种情况,您将收到UnboundLocalError。
你可以通过在for循环之前声明i变量来解决这个问题,以防它不能运行(一个简单的i = 2
)
正如Python Zen本身所说 explicit比隐式更好,通过对中断后想要保留的结果使用不同的变量,你可以使这个值显式而不是隐含到循环后的i
变量。
示例:
def thousandthPrime():
count = 0
candidate = 5 # candidates for prime no. these are all odd no.s Since starts at 5 therefore we find 998th prime no. as 2 and 3 are already prime no.s
while(True):
# print 'Checking =',candidate
useful_divider = 2
for i in range(2, candidate / 2): # if any number from 2 to candidate/2 can divide candidate with remainder = 0 then candidate is not a prime no.
if candidate % i == 0:
useful_divider = i
break
if useful_divider == (candidate / 2) - 1: # If none divide it perfectly, useful_divider will reach candidate/2-1 eventually. So, this is a prime number.
count+=1
print 'No. of prime no.s found excluding 2 and 3 =',count, '--->',candidate
# And so on...
# ... and so on :)