Frage

Könnte mir bitte jemand sagen, was ich mit diesem Code falsch machen werde? Es druckt nur ‚count‘ sowieso. Ich will nur einen sehr einfachen Prime-Generator (nichts Besonderes).

import math

def main():
    count = 3
    one = 1
    while one == 1:
        for x in range(2, int(math.sqrt(count) + 1)):
            if count % x == 0: 
                continue
            if count % x != 0:
                print count

        count += 1
War es hilfreich?

Lösung

Es gibt einige Probleme:

  • Warum drucken Sie aus Zählung, wenn es nicht durch x dividieren hat? Es bedeutet nicht, es ist Primzahl, es bedeutet nur, dass diese besondere x es nicht teilen
  • continue geht in die nächste Schleife Iteration - aber Sie wirklich wollen, um es zu stoppen break mit

Hier ist der Code mit ein paar Korrekturen, es druckt nur Primzahlen:

import math

def main():
    count = 3
    
    while True:
        isprime = True
        
        for x in range(2, int(math.sqrt(count) + 1)):
            if count % x == 0: 
                isprime = False
                break
        
        if isprime:
            print count
        
        count += 1

Für viele effiziente prime Generation finden Sie im Sieb des Erastothenes, wie andere vorgeschlagen haben. Hier ist eine schöne, optimierte Implementierung mit vielen Kommentaren:

# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/

def gen_primes():
    """ Generate an infinite sequence of prime numbers.
    """
    # Maps composites to primes witnessing their compositeness.
    # This is memory efficient, as the sieve is not "run forward"
    # indefinitely, but only as long as required by the current
    # number being tested.
    #
    D = {}
    
    # The running integer that's checked for primeness
    q = 2
    
    while True:
        if q not in D:
            # q is a new prime.
            # Yield it and mark its first multiple that isn't
            # already marked in previous iterations
            # 
            yield q
            D[q * q] = [q]
        else:
            # q is composite. D[q] is the list of primes that
            # divide it. Since we've reached q, we no longer
            # need it in the map, but we'll mark the next 
            # multiples of its witnesses to prepare for larger
            # numbers
            # 
            for p in D[q]:
                D.setdefault(p + q, []).append(p)
            del D[q]
        
        q += 1

Beachten Sie, dass es einen Generator zurückgibt.

Andere Tipps

def is_prime(num):
    """Returns True if the number is prime
    else False."""
    if num == 0 or num == 1:
        return False
    for x in range(2, num):
        if num % x == 0:
            return False
    else:
        return True

>> filter(is_prime, range(1, 20))
  [2, 3, 5, 7, 11, 13, 17, 19]

Wir werden alle Primzahlen bis zu 20 in einer Liste bekommen. Ich hätte Sieb des Eratosthenes verwendet, aber sie sagte Sie wollen etwas, das ganz einfach. ;)

print [x for x in range(2,100) if not [t for t in range(2,x) if not x%t]]

re ist mächtig:

import re


def isprime(n):
    return re.compile(r'^1?$|^(11+)\1+$').match('1' * n) is None

print [x for x in range(100) if isprime(x)]

###########Output#############
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
def primes(n): # simple Sieve of Eratosthenes 
   odds = range(3, n+1, 2)
   sieve = set(sum([range(q*q, n+1, q+q) for q in odds],[]))
   return [2] + [p for p in odds if p not in sieve]

>>> primes(50)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Um zu testen, ob eine Zahl prim ist:

>>> 541 in primes(541)
True
>>> 543 in primes(543)
False

Hier ist eine einfach (Python 2.6.2) Lösung ..., die mit dem OP ursprünglichen Anfrage (jetzt sechs Monate alt) online ist; und sollte eine durchaus akzeptable Lösung in jeder sein „Programmierung 101“ Natürlich ... also diesen Beitrag.

import math

def isPrime(n):
    for i in range(2, int(math.sqrt(n)+1)):
        if n % i == 0: 
            return False;
    return n>1;

print 2
for n in range(3, 50):
    if isPrime(n):
        print n

Diese einfache „Brute-Force-Methode“ ist „schnell genug“ für die Zahlen bis zu etwa 16.000 auf moderne PCs (dauerte ca. 8 Sekunden auf meinem 2GHz Kasten).

Offensichtlich ist dies effizient viel mehr getan werden könnte, indem sie nicht die primeness jeder geraden Zahl neu zu berechnen, oder jedes Vielfaches von 3, 5, 7, usw. für jede einzelne Zahl ... Siehe Sieb des Eratosthenes oder sogar die Sieb des Atkin wenn Sie das Gefühl besonders mutig und / oder verrückt.

Gewährleistungsausschluß: Ich bin ein Python-Noob. Bitte nehmen Sie nicht alles, was ich sagen als Evangelium.

Zu meiner Meinung nach ist es immer am besten, den funktionalen Ansatz,

So ich eine Funktion zuerst herausfinden, ob die Zahl eine Primzahl ist oder nicht, dann verwenden Sie es in Schleife oder einer anderen Stelle als notwendig.

def isprime(n):
      for x in range(2,n):
        if n%x == 0:
            return False
    return True

Dann einen einfachen Liste Verständnis oder Generator Ausdruck führen Sie Ihre Liste von vorrangiger zu bekommen,

[x for x in range(1,100) if isprime(x)]

Das scheint Hausaufgaben-y, also werde ich einen Hinweis, anstatt eine detaillierte Erklärung geben. Korrigieren Sie mich, wenn ich falsch angenommen haben.

Sie sind wohlauf so weit wie Rettung, wenn Sie einen noch Teiler zu sehen.

Aber Sie drucken ‚count‘, sobald Sie auch sehen ein Zahl, die nicht in sie nicht teilt. 2, zum Beispiel, teilt sich nicht gleichmäßig in 9. Aber das nicht 9a prime machen. Vielleicht möchten Sie gehen zu halten, bis Sie sicher sind, nicht Zahl im Bereich Streichhölzer.

(wie andere geantwortet haben, ist ein Sieb mit einem viel effizienteren Weg zu gehen ... nur versuchen, Ihnen zu helfen, zu verstehen, warum dieser spezifische Code tut nicht, was Sie wollen)

Wie wäre es damit, wenn Sie die Primzahl berechnen direkt:

def oprime(n):
counter = 0
b = 1
if n == 1:
    print 2
while counter < n-1:
    b = b + 2
    for a in range(2,b):
        if b % a == 0:
            break
    else:
        counter = counter + 1
        if counter == n-1:
            print b

Ein weiteres einfaches Beispiel mit einer einfachen Optimierung der nur ungerade Zahlen berücksichtigen. Alles getan, was mit Lazy-Streams (Python-Generatoren).

Verbrauch: Primzahlen = list (create_prime_iterator (1, 30))

import math
import itertools

def create_prime_iterator(rfrom, rto):
    """Create iterator of prime numbers in range [rfrom, rto]"""
    prefix = [2] if rfrom < 3 and rto > 1 else [] # include 2 if it is in range separately as it is a "weird" case of even prime
    odd_rfrom = 3 if rfrom < 3 else make_odd(rfrom) # make rfrom an odd number so that  we can skip all even nubers when searching for primes, also skip 1 as a non prime odd number.
    odd_numbers = (num for num in xrange(odd_rfrom, rto + 1, 2))
    prime_generator = (num for num in odd_numbers if not has_odd_divisor(num))
    return itertools.chain(prefix, prime_generator)

def has_odd_divisor(num):
    """Test whether number is evenly divisable by odd divisor."""
    maxDivisor = int(math.sqrt(num))
    for divisor in xrange(3, maxDivisor + 1, 2):
        if num % divisor == 0:
            return True
    return False

def make_odd(number):
    """Make number odd by adding one to it if it was even, otherwise return it unchanged"""
    return number | 1

Hier ist eine Version von numpy Sieb des Eratosthenes sowohl Ordnung Komplexität aufweist (niedriger als ein Array mit der Länge n Sortierung) und Vektorisierung.

import numpy as np 
def generate_primes(n):
    is_prime = np.ones(n+1,dtype=bool)
    is_prime[0:2] = False
    for i in range(int(n**0.5)+1):
        if is_prime[i]:
            is_prime[i*2::i]=False
    return np.where(is_prime)[0]

Timings:

import time    
for i in range(2,10):
    timer =time.time()
    generate_primes(10**i)
    print('n = 10^',i,' time =', round(time.time()-timer,6))

>> n = 10^ 2  time = 5.6e-05
>> n = 10^ 3  time = 6.4e-05
>> n = 10^ 4  time = 0.000114
>> n = 10^ 5  time = 0.000593
>> n = 10^ 6  time = 0.00467
>> n = 10^ 7  time = 0.177758
>> n = 10^ 8  time = 1.701312
>> n = 10^ 9  time = 19.322478
  • Die continue-Anweisung sieht falsch aus.

  • Sie möchten bei 2, da 2 ist die erste Primzahl ist.

  • starten
  • Sie können schreiben "während True:" eine Endlosschleife bekommen

  • .

Sie müssen sicherstellen, dass alle möglichen Teilern nicht teilen gleichmäßig die Anzahl Sie überprüfen. In diesem Fall werde drucken Sie die Nummer, die Sie jederzeit sind die Überprüfung nur eine der möglichen Teilern teilt sich nicht gleichmäßig die Nummer.

Sie wollen ja auch keine Aussage verwenden, fortgesetzt werden, da ein weiterhin nur es zu dem nächsten möglichen Divisor zu überprüfen, wenn Sie bereits herausgefunden, dass die Zahl keine Primzahl sind.

Hier ist, was ich habe:

def is_prime(num):
    if num < 2:         return False
    elif num < 4:       return True
    elif not num % 2:   return False
    elif num < 9:       return True
    elif not num % 3:   return False
    else:
        for n in range(5, int(math.sqrt(num) + 1), 6):
            if not num % n:
                return False
            elif not num % (n + 2):
                return False

    return True

Es ist ziemlich schnell für eine große Zahl, da es nur Kontrollen gegen bereits Primzahlen für Teilern einer Zahl.

Nun, wenn Sie eine Liste von Primzahlen erzeugen möchten, können Sie tun:

# primes up to 'max'
def primes_max(max):
    yield 2
    for n in range(3, max, 2):
        if is_prime(n):
            yield n

# the first 'count' primes
def primes_count(count):
    counter = 0
    num = 3

    yield 2

    while counter < count:
        if is_prime(num):
            yield num
            counter += 1
        num += 2

mit Generatoren hier könnte für Effizienz gewünscht werden.

Und gerade als Referenz, anstatt zu sagen:

one = 1
while one == 1:
    # do stuff

Sie können einfach sagen:

while 1:
    #do stuff
mit Listenkomprehensionen in einer recht elegante Art und Weise

Sie können eine Liste von Primzahlen erstellen. Genommen von hier:

>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
>>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
def genPrimes():
    primes = []   # primes generated so far
    last = 1      # last number tried
    while True:
        last += 1
        for p in primes:
            if last % p == 0:
                break
        else:
            primes.append(last)
            yield last

ähnlich wie user107745, aber ‚alle‘ statt doppelter Verneinung mit (etwas besser lesbar, aber ich denke, gleiche Leistung):

import math
[x for x in xrange(2,10000) if all(x%t for t in xrange(2,int(math.sqrt(x))+1))]

Im Grunde durchläuft es die x in Reichweite von mehr als (2, 100) und Kommissionierung nur diejenigen, die nicht mod == 0 für alle t in Bereich haben Sie (2, x)

Eine andere Art und Weise wahrscheinlich nur die Primzahlen bevölkern, wie wir gehen:

primes = set()
def isPrime(x):
  if x in primes:
    return x
  for i in primes:
    if not x % i:
      return None
  else:
    primes.add(x)
    return x

filter(isPrime, range(2,10000))
def check_prime(x):
    if (x < 2): 
       return 0
    elif (x == 2): 
       return 1
    t = range(x)
    for i in t[2:]:
       if (x % i == 0):
            return 0
    return 1

SymPy ist eine Python-Bibliothek für symbolische Mathematik. Es verfügt über einige Funktionen Primzahlen zu erzeugen.

isprime(n)              # Test if n is a prime number (True) or not (False).

primerange(a, b)        # Generate a list of all prime numbers in the range [a, b).
randprime(a, b)         # Return a random prime number in the range [a, b).
primepi(n)              # Return the number of prime numbers less than or equal to n.

prime(nth)              # Return the nth prime, with the primes indexed as prime(1) = 2. The nth prime is approximately n*log(n) and can never be larger than 2**n.
prevprime(n, ith=1)     # Return the largest prime smaller than n
nextprime(n)            # Return the ith prime greater than n

sieve.primerange(a, b)  # Generate all prime numbers in the range [a, b), implemented as a dynamically growing sieve of Eratosthenes. 

Hier sind einige Beispiele.

>>> import sympy
>>> 
>>> sympy.isprime(5)
True
>>> list(sympy.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> sympy.randprime(0, 100)
83
>>> sympy.randprime(0, 100)
41
>>> sympy.prime(3)
5
>>> sympy.prevprime(50)
47
>>> sympy.nextprime(50)
53
>>> list(sympy.sieve.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

Wenn Sie wollte alle Primzahlen in einem Bereich finden Sie dies tun könnte:

def is_prime(num):
"""Returns True if the number is prime
else False."""
if num == 0 or num == 1:
    return False
for x in range(2, num):
    if num % x == 0:
        return False
else:
    return True
num = 0
itr = 0
tot = ''
while itr <= 100:
    itr = itr + 1
    num = num + 1
    if is_prime(num) == True:
        print(num)
        tot = tot + ' ' + str(num)
print(tot)

Just while its <= und Ihre Nummer für den Bereich hinzufügen.
OUTPUT:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101

Mit Generator:

def primes(num):
    if 2 <= num:
        yield 2
    for i in range(3, num + 1, 2):
        if all(i % x != 0 for x in range(3, int(math.sqrt(i) + 1))):
            yield i

Verbrauch:

for i in primes(10):
    print(i)
  

2, 3, 5, 7

import time

maxnum=input("You want the prime number of 1 through....")

n=2
prime=[]
start=time.time()

while n<=maxnum:

    d=2.0
    pr=True
    cntr=0

    while d<n**.5:

        if n%d==0:
            pr=False
        else:
            break
        d=d+1

    if cntr==0:

        prime.append(n)
        #print n

    n=n+1

print "Total time:",time.time()-start

Für mich sieht die folgende Lösung einfach und leicht zu folgen.

import math

def is_prime(num):

    if num < 2:
        return False

    for i in range(2, int(math.sqrt(num) + 1)):
        if num % i == 0:
            return False

return True
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top