Simple Prime Generator en Python

quelqu'un pourrait-il s'il vous plaît me dire ce que je fais de mal avec ce code? C'est juste imprimer "count" de toute façon. Je veux juste un générateur de prime très simple (rien de fantaisiste).

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
30
demandé sur fortunate_man 2009-02-20 00:22:24

22 réponses

Il y a quelques problèmes:

  • pourquoi imprimer count alors qu'il ne se divise pas par x? Cela ne veut pas dire que c'est premier, mais seulement que ce x particulier ne le divise pas!--8-->
  • continue passe à la prochaine itération de boucle - mais vous voulez vraiment arrêter à l'aide de break

Voici votre code avec quelques corrections, il n'imprime que des nombres premiers:

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

pour la génération prime beaucoup plus efficace, voir le tamis D'Erastothènes, comme d'autres ont suggéré. Voici une belle implémentation optimisée avec de nombreux commentaires:

# 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

Notez qu'il renvoie d'un générateur.

131
répondu Eli Bendersky 2015-09-03 19:51:29
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]

Nous allons obtenir tous les nombres premiers jusqu'à 20 dans une liste. J'aurais pu utiliser un tamis D'Eratosthène mais vous avez dit vous voulez quelque chose de très simple. ;)

12
répondu aatifh 2009-03-18 19:35:23
print [x for x in range(2,100) if not [t for t in range(2,x) if not x%t]]
7
répondu SergioAraujo 2010-04-12 18:28:58

re est puissant:

import re


def isprime(n):
    return re.compile(r'^1?$|^(11+)+$').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]
6
répondu FelixHo 2015-11-27 07:09:37
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]

Pour tester si un nombre est premier:

>>> 541 in primes(541)
True
>>> 543 in primes(543)
False
4
répondu dansalmo 2013-10-21 15:19:17

Voici un simple (Python 2.6.2) solution... ce qui est conforme à la demande initiale de L'OP (qui date maintenant de six mois); et devrait être une solution parfaitement acceptable dans tout cours de "programmation 101"... D'où ce post.

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

cette méthode simple "brute force" est "assez rapide" pour les nombres jusqu'à environ 16.000 sur PC moderne (a pris environ 8 secondes sur ma boîte de 2GHz).

évidemment, cela pourrait être fait beaucoup plus efficacement, en ne recalculant pas le primeness de chaque nombre pair, ou tout multiple de 3, 5, 7, etc pour chaque numéro unique... Voir le tamis D'Eratosthènes (voir la mise en œuvre d'eliben ci-dessus), ou même le tamis D'Atkin si vous vous sentez particulièrement courageux et/ou fou.

Caveat Emptor: je suis un python de noob. Ne prenez rien de ce que je dis comme Évangile.

3
répondu corlettk 2014-05-21 15:34:54

donc je crée d'abord une fonction pour savoir si le nombre est Premier ou ne pas l'utiliser en boucle ou à un autre endroit si nécessaire.

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

puis lancez une simple expression de compréhension de liste ou de générateur pour obtenir votre liste de prime,

[x for x in range(1,100) if isprime(x)]
2
répondu mmrs151 2012-04-27 10:01:25

Cela semble devoirs-y, donc, je vais donner un indice plutôt qu'une explication détaillée. Corrigez-moi si j'ai supposé mal.

Vous faites bien comme renflouer quand vous voyez un même diviseur.

mais vous imprimez 'count' dès que vous voyez même nombre qui ne divise pas. 2, par exemple, ne se divise pas également en 9. Mais ça ne fait pas de 9 un prime. Vous pourriez vouloir continuer à aller jusqu'à ce que vous êtes sûr aucun dans la plage de matchs.

(comme d'autres ont répondu, le Tamis est une façon beaucoup plus efficace d'aller... juste essayer de vous aider à comprendre pourquoi ce code n'est pas de faire ce que vous voulez)

1
répondu Paul Roub 2009-02-19 21:36:57

Que Diriez-vous de ceci si vous voulez calculer la prime directement:

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
1
répondu Jitender Shekhawat 2012-02-12 07:04:00

un autre exemple simple, avec une optimisation simple de ne considérer que les nombres impairs. Tout est fait avec des flux paresseux (générateurs python).

Utilisation: amorce = liste(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
1
répondu Sharas 2013-06-06 10:32:59
  • la déclaration continue semble fausse.

  • Vous souhaitez démarrer à 2 car 2 est le premier nombre premier.

  • Vous pouvez écrire "while True:" pour obtenir une boucle infinie.

0
répondu starblue 2009-02-19 21:30:06

vous devez vous assurer que tous les diviseurs possibles ne divisent pas également le nombre que vous vérifiez. Dans ce cas, vous imprimerez le nombre que vous vérifiez à tout moment juste un des diviseurs possibles ne divise pas également le nombre.

vous ne voulez pas non plus utiliser une instruction continuer parce qu'une suite la causera juste pour vérifier le diviseur suivant possible quand vous avez déjà découvert que le nombre n'est pas un premier.

0
répondu David Locke 2009-02-19 21:35:36

Voici ce que j'ai:

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

c'est assez rapide pour les grands nombres, car il vérifie seulement contre les nombres déjà premiers pour les diviseurs d'un nombre.

Maintenant, si vous voulez générer une liste de nombres premiers, vous pouvez faire:

# 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

l'utilisation de générateurs ici pourrait être souhaitable pour l'efficacité.

Et juste pour la référence, au lieu de dire:

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

vous pouvez simplement dire:

while 1:
    #do stuff
0
répondu fengshaun 2009-03-18 21:04:40

Vous pouvez créer une liste de nombres premiers en utilisant des compréhensions de liste d'une manière assez élégante. Prises de ici:

>>> 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]
0
répondu randlet 2009-03-19 00:37:50
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
0
répondu Kuldeep K. Rishi 2013-03-23 13:52:26

similaire à user107745, mais en utilisant ' all ' au lieu de la double négation (un peu plus lisible, mais je pense que la même performance):

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

fondamentalement, il itère sur x dans la gamme de (2, 100) et ne sélectionne que ceux qui n'ont pas mod == 0 pour tout t dans la gamme(2,x)

une Autre façon est probablement juste de peupler le premier des nombres, comme nous allons:

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))
0
répondu vtlinh 2013-09-27 22:17:39
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
0
répondu kn3l 2014-03-17 02:20:04

SymPy est une bibliothèque Python pour les mathématiques symboliques. Il offre plusieurs fonctions pour générer des nombres premiers.

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. 

Ici sont quelques exemples.

>>> 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]
0
répondu SparkAndShine 2017-02-24 13:43:42

si vous voulez trouver tous les nombres premiers dans une plage, vous pouvez faire ceci:

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)

il suffit d'ajouter while its <= et votre numéro pour la gamme.

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

0
répondu user9311010 2018-03-12 01:03:10

Voici une version compacte du tamis D'Eratosthènes ayant à la fois une complexité acceptable (plus faible que le tri d'un tableau de longueur n) et une vectorisation.

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]

Horaires:

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
0
répondu Peter Mølgaard Pallesen 2018-07-20 06:59:06
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
-1
répondu David B Carmack 2014-10-22 22:13:43

pour moi, la solution ci-dessous semble simple et facile à suivre.

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
-1
répondu user007 2017-02-21 14:03:03