这可以更加pythonic?

Mer*_*nel 2 python primes

我刚才遇到过这个(真的)简单的程序.它只输出第一个x素数.我很尴尬地问,有没有办法让它更"pythonic",即凝聚它,使其(更多)可读?切换功能很好; 我只对可读性感兴趣.

谢谢

from math import sqrt


def isprime(n):
  if n ==2:
    return True
  if n % 2 ==0 : # evens
    return False

  max = int(sqrt(n))+1 #only need to search up to sqrt n 
  i=3
  while i <= max: # range starts with 3 and for odd i
    if n % i == 0:
      return False
    i+=2

  return True



reqprimes = int(input('how many primes: '))
primessofar = 0
currentnumber = 2
while primessofar < reqprimes:

  result = isprime(currentnumber)

  if result:
     primessofar+=1
     print currentnumber
     #print '\n'

  currentnumber += 1
Run Code Online (Sandbox Code Playgroud)

Dar*_*rio 7

您的算法本身可以通过pythonically实现,但以功能方式重新编写算法通常很有用 - 您可能最终会得到一个完全不同但更易读的解决方案(甚至更加pythonic).

def primes(upper):
    n = 2; found = []
    while n < upper:
        # If a number is not divisble through all preceding primes, it's prime
        if all(n % div != 0 for div in found):
            yield n
            found.append( n )
        n += 1
Run Code Online (Sandbox Code Playgroud)

用法:

for pr in primes(1000):
    print pr
Run Code Online (Sandbox Code Playgroud)

或者,考虑到Alasdair的评论,更高效的版本:

from math import sqrt
from itertools import takewhile

def primes(upper):
    n = 2; foundPrimes = []
    while n < upper:
        sqrtN = int(sqrt(n))
        # If a number n is not divisble through all preceding primes up to sqrt(n), it's prime
        if all(n % div != 0 for div in takewhile(lambda div: div <= sqrtN, foundPrimes)):
            yield n
            foundPrimes.append(n)
        n += 1
Run Code Online (Sandbox Code Playgroud)


Ste*_*202 6

给定的代码效率不高.替代解决方案(效率低下):

>>> from math import sqrt
>>> def is_prime(n):
...     return all(n % d for d in range(2, int(sqrt(n)) + 1))
... 
>>> def primes_up_to(n):
...     return filter(is_prime, range(2, n))
... 
>>> list(primes_up_to(20))
[2, 3, 5, 7, 11, 13, 17, 19]
Run Code Online (Sandbox Code Playgroud)

此代码使用all,range,int,math.sqrt,filterlist.它与您的代码不完全相同,因为它打印的素数达到一定数量,而不是n个素数.为此,您可以:

>>> from itertools import count, islice
>>> def n_primes(n):
...     return islice(filter(is_prime, count(2)), n)
... 
>>> list(n_primes(10))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Run Code Online (Sandbox Code Playgroud)

这引入了另外两个功能,即itertools.countitertools.islice.(最后一段代码仅适用于Python 3.x;在Python 2.x中,使用itertools.ifilter而不是filter.)


  :更有效的方法是使用Eratosthenes筛.


Mar*_*ers 5

风格指南中的一些小事.

  • 使用四个空格,而不是两个空格.(我个人更喜欢标签,但这不是Pythonic方式.)
  • 空白线较少.
  • 一致的空格:n ==2:=>n == 2:
  • 在变量名称中使用下划线:currentnumber=>current_number

    • 另外,不鼓励使用“max”作为变量名,因为它掩盖了内置 max 函数。 (2认同)