我刚刚回到Project Euler并且丢失了我的帐户和解决方案,所以我回到了问题7.但是,我的代码不起作用。这对我来说似乎相当原始,有人可以帮助我调试我的(短)脚本吗?
应该找到10001 Prime。
#!/usr/bin/env python
#encoding: utf-8
"""
P7.py
Created by Andrew Levenson on 2010-06-29.
Copyright (c) 2010 __ME__. All rights reserved.
"""
import sys
import os
from math import sqrt
def isPrime(num):
flag = True
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
if flag == True:
return True
else:
return False
def main():
i, n = 1, 3
p = False
end = 6
while end - i >= 0:
p = isPrime(n)
if p == True:
i = i + 1
print n
n = n + 1
if __name__ == '__main__':
main()
编辑*:抱歉,问题是它说每个号码都是素数。 :/
答案 0 :(得分:5)
语法很好(在Python 2中)。语义有一些可避免的复杂性,以及这个一个一个错误:
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
range(2, Y)
从2包含到Y
排除 - 所以你经常不检查最后一个可能的除数,从而认为“素数”不是很多数字吨。作为最简单的修复,请在1 + int(...
中尝试range
。之后,建议删除那些可避免的并发症:例如,
if somebool: return True
else: return False
永远不会被保证,因为更简单的return somebool
做同样的工作。
整个代码的简化版本(只有必不可少的优化,但在其他方面完全相同的算法)可能是,例如:
from math import sqrt
def isPrime(num):
for x in range(3, int(1 + sqrt(num)), 2):
if num % x == 0: return False
return True
def main():
i, n = 0, 3
end = 6
while i < end:
if isPrime(n):
i += 1
print n
n += 2
if __name__ == '__main__':
main()
“一旦你知道答案就回来”已经解释了,我已经为n
添加了一个更重要的优化(+ = 2,而不是1),因为我们“知道”偶数&gt; 3不是素数,而range
的调整也是出于同样的原因。)
有可能变得可爱,例如:
def isPrime(num):
return all(num % x for x n range(3, int(1 + sqrt(num)), 2))
虽然如果你不熟悉内置的all
这看起来可能看起来不那么“简单”,但实际上是这样,因为它可以节省你必须做的事情(并且代码的读者必须遵循)低级别逻辑,有利于适当的抽象层次来表达函数的关键思想,即“如果在尝试除法时所有可能的奇数除数都有[[非0]]余数,则”num为素数“(即表示概念直接以精确,可执行的形式)。内部算法实际上仍然相同。
更进一步......:
import itertools as it
def odd():
for n in it.count(1):
yield n + n + 1
def main():
end = 5
for i, n in enumerate(it.ifilter(isPrime, odd())):
print n
if i >= end: break
同样,这只是与以前相同的算法,只是在更合适的抽象层次上表达:将奇数序列(从3包括在内)的生成放入其自己的odd
生成器中,并且使用enumerate
内置和itertools
功能来避免不适当(和不需要的)低级表达/推理。
我再说一遍:还没有应用基本优化 - 只是合适的抽象。 Python中无限连续素数生成的优化(例如通过开放式Eratosthenes Sieve方法)已在其他地方进行了深入讨论,例如: here(请务必查看评论!)。在这里,我专注于展示(使用内置插件,如enumerate
,all
和any
,关键itertools
,以及生成器和生成器表达式) “在现代Python中,问题可以在更适当的抽象层次上表达,而不是”C启发式“,对于大多数编程人员来说,这些问题对于C编程等都是最自然的。 (对于习惯于Stepanov首先确定的C ++的“抽象惩罚”的学者来说,可能令人惊讶的是,Python通常倾向于具有“抽象溢价”,特别是如果以其超快的速度而闻名的itertools
被广泛和恰当地使用。 ..但是,这真的是一个不同的主题; - )。
答案 1 :(得分:1)
这不是更好吗?
def isPrime(num):
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
return False
return True
而且:
def main():
i, n = 1, 3
while i <= 6:
if isPrime(n):
i = i + 1
print n
n = n + 1
另外,我在那里找不到10001
......