next(i for i in itertools.imap(lambda x: random.randint(p,q)|1,itertools.count()) if isPrime(i))
Questo inizia con itertools.count() - questo dà un insieme infinito.
Ogni numero è mappato a un nuovo numero casuale nell'intervallo, da itertools.imap(). imap è come una mappa, ma restituisce un iteratore, piuttosto che una lista - non vogliamo generare una lista di numeri casuali inifiniti!
Quindi, il primo numero corrispondente viene trovato e restituito.
Funziona in modo efficiente, anche se p e q sono molto distanti - ad es. 1 e 10 ** 30, che non generano una lista completa!
A proposito, questo non è più efficiente del tuo codice sopra, ed è molto più difficile da capire a colpo d'occhio - ti preghiamo di avere qualche considerazione per il prossimo programmatore di dover leggere il tuo codice, e fallo come hai fatto sopra. Quel programmatore potrebbe essere tu tra sei mesi, quando hai dimenticato cosa doveva fare questo codice!
P.S - in pratica, si potrebbe voler sostituire count() con xrange (NON range!) Ad es. xrange((p-q)**1.5+20)
non fare più di quel numero di tentativi (bilanciati tra test limitati per intervalli piccoli e grandi gamme, e non ha più dell'1/2% di possibilità di fallire se potesse riuscire), altrimenti, come è stato suggerito in un altro post, potrebbe loop per sempre.
PPS - miglioramento: sostituito random.randint(p,q)
con random.randint(p,q)|1
- questo rende il codice di due volte più efficiente, ma elimina la possibilità che il risultato sarà 2.
fonte
2015-01-08 01:17:56
Sembra che sarebbe meglio generare un elenco di numeri primi tra 'p' e' q' e quindi scegliere uno casuale da quella lista. –
È possibile aumentare le probabilità che un numero sia primo impostando il bit più basso su 1, rendendolo così strano - c'è solo un primo numero pari, ovvero 2. In realtà, tutti i numeri primi diversi da 2 e 3 sono uno sotto o uno sopra un multiplo di sei. –
Odio quando qualcuno proroga una domanda senza dire perché, perché l'OP non può risolverlo se non sa cosa è sbagliato. –