Python语法问题

时间:2010-06-29 15:42:53

标签: python primes

我刚刚回到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()

编辑*:抱歉,问题是它说每个号码都是素数。 :/

2 个答案:

答案 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(请务必查看评论!)。在这里,我专注于展示(使用内置插件,如enumerateallany,关键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 ......