Ich bin seit einer Weile dabei, mich in Python (3.1 und 3.2) einzuarbeiten. Vor ein paar Tagen habe ich versucht mit den Möglichkeiten, die Python so bietet einen möglichst kurzen Primzahlentest (auf Basis einfacher Modulooperationen, nichts elaboriertes wie der Miller-Rabin-Test oder so) zu basteln und bin bei einem Einzeiler gelandet.
Da kam mir die Idee, dass ich darauf aufbauend systematisch Primzahlenlücken (http://oeis.org/A001223) berechnen könnte.
Nach einigem Basteln landete ich irgendwann bei Folgendem:
Code: Alles auswählen
from functools import partial
from operator import mod
from itertools import tee
from time import time
def create_prime_tester(seed=[2]):
prime_list = seed
def check_prime(inpt_numb):
if not inpt_numb in prime_list:
test_res = all(map(partial(mod, inpt_numb), prime_list))
if test_res == True:
prime_list.append(inpt_numb)
return(test_res)
elif inpt_numb in prime_list:
return(True)
return(check_prime)
if __name__ == '__main__':
is_prime = create_prime_tester()
inpt = int(input("N: "))
start_time = time()
prime_gen = (i for i in range(3, inpt, 2) if is_prime(i) == True)
###
prime_gen_a, prime_gen_b = tee(prime_gen, 2)
next(prime_gen_b)
deltas = ((i, j, i-j) for i, j in zip(prime_gen_b, prime_gen_a))
for i, j, k in deltas:
print ("{0}\t\t{1}\t\t{2}".format(i, j, k))
###
stop_time = time()
print("Duration:", stop_time - start_time)
Für etwas größere Zahlen wird das aber schnell relativ langsam (für Primzahlen bis 1.000.000 je nach Rechner 20 1,5 - 2 Std. wenn ich das richtig im Kopf habe).
Teilweise habe ich auch andere Implementationen versucht, konnte aber aufgrund der langen Laufzeit für größere Zahlen oftmals nicht feststellen, ob die Unterschiede natürliche Schwankungen sind, oder nicht.
Für die Berechnung der Differenz hatte ich noch folgenden Kandidaten, der mit einem Generator weniger auskommt:
Code: Alles auswählen
[...]
first = next(prime_gen)
while True:
try:
second = next(prime_gen)
except StopIteration:
break
delta = second - first
print ("{0}\t\t{1}\t\t{2}".format(second, first, delta))
first = second
[...]
Die konkrete Programmieraufgabe selbst ist nebensächlich. Mir geht es eher um Folgendes:
Wie erreiche ich die optimale Implementierung, unter Beibehaltung der prinzipiellen Idee (Also Primzahlentest per Modulo, und anschließende Differenzbildung und ohne andere Ansätze wie andere Primzahlentest, oder Verwendung mehrerer Threads etc.)?
Kann man das so machen, wie ich das mir gedacht habe, oder sind da Sachen drin, die schlechter Programmierstil, pythonfremd, oder ineffizient sind?
Mir geht es darum, Python anständig zu lernen, und mir keine komischen Dinge anzugewöhnen.
Bin für jede Art von Anmerkung oder Kritik dankbar.