26.2 Zufallszahlengenerator – random 

Das Modul random der Standardbibliothek erzeugt Pseudozufallszahlen und bietet zusätzliche Funktionen, um zufallsgesteuerte Operationen auf Basisdatentypen anzuwenden.
[»] Hinweis
Das Modul random erzeugt keine echten Zufallszahlen, sondern sogenannte Pseudozufallszahlen. Echte Zufallszahlen sind für einen Computer nicht berechenbar. Ein Generator für Pseudozufallszahlen wird mit einer ganzen Zahl initialisiert und erzeugt aufgrund dieser Basis eine deterministische, aber scheinbar zufällige Abfolge von Pseudozufallszahlen. Diese Zahlenfolge wiederholt sich dabei nach einer gewissen Anzahl von erzeugten Zufallszahlen. Im Falle des in Python standardmäßig verwendeten Algorithmus beträgt diese Periode 219937–1 Zahlen.
Der in random implementierte Generator für Pseudozufallszahlen lässt sich mithilfe der Funktion seed initialisieren:
>>> import random
>>> random.seed(12)
Wenn es sich bei der Seed um eine ganze Zahl handelt, wird der Zufallszahlengenerator direkt mit dieser Zahl, ansonsten mit dem Hash-Wert der übergebenen Instanz initialisiert. Wenn kein Parameter übergeben wird, wird der Zufallszahlengenerator mit der aktuellen Systemzeit initialisiert. Auf diese Weise können die erzeugten Zahlen als quasi-zufällig angesehen werden:
>>> random.seed()
Wird der Zufallszahlengenerator zu unterschiedlichen Zeiten mit demselben Wert initialisiert, erzeugt er jeweils dieselbe Zahlenfolge.
26.2.1 Den Status speichern und laden 

Die Funktion getstate gibt ein Tupel zurück, das den aktuellen Status des Zufallszahlengenerators beschreibt. Mithilfe der Funktion setstate lässt sich damit der Status des Generators speichern und zu einem späteren Zeitpunkt, beispielsweise nach zwischenzeitlicher Neuinitialisierung, wiederherstellen:
>>> state = random.getstate()
>>> random.setstate(state)
Der Generator läuft dann so weiter, als hätte es die Unterbrechung nicht gegeben.
26.2.2 Zufällige ganze Zahlen erzeugen 

Zur Erzeugung einer (pseudo-)zufälligen ganzen Zahl existiert die Funktion randint, der die gewünschten Intervallgrenzen übergeben werden können.
>>> random.randint(0, 10)
4
In diesem Fall werden zufällig ganze Zahlen zwischen 0 und 10 erzeugt, wobei die Intervallgrenzen 0 und 10 ebenfalls gültige Ergebnisse sein können.
Etwas mehr Kontrolle über die möglichen Ergebnisse erlaubt die Funktion randrange. Sie gibt ein zufällig gewähltes Element aus dem Zahlenraum zurück, den ein Aufruf der Built-in Function range mit den gleichen Parametern erzeugen würde:
>>> random.randrange(0, 50, 2)
40
In diesem Fall wurde eine zufällige gerade Zahl zwischen 0 und 50 erzeugt.
Eine weitere Möglichkeit zur Erzeugung zufälliger Zahlen ist die Funktion getrandbits, die eine zufällige Bit-Folge festgelegter Länge erzeugt und als ganze Zahl zurückgibt.
>>> random.getrandbits(8)
156
In diesem Fall wurde die Funktion getrandbits verwendet, um ein zufälliges Byte zu erzeugen.
26.2.3 Zufällige Gleitkommazahlen erzeugen 

Das Modul random enthält einige Funktionen zur Erzeugung einer zufälligen Gleitkommazahl nach einer gewählten Wahrscheinlichkeitsverteilung. Die einfachste dieser Funktionen ist random, mit deren Hilfe eine gleich verteilte Zufallszahl zwischen 0 und 1 erzeugt wird:
>>> random.random()
0.6018018690250143
Die verwandte Funktion uniform erzeugt eine gleichverteilte Zufallszahl innerhalb der angegebenen Intervallgrenzen:
>>> random.uniform(0, 10)
5.044950881560962
Darüber hinaus enthält das Modul random eine Reihe weiterer Funktionen, die Zufallszahlen nach mehr oder weniger exotischen Wahrscheinlichkeitsverteilungen erzeugen. Die bekannteste dieser Verteilungen ist die Normal- oder Gauß-Verteilung. Eine normalverteilte Zufallszahl können Sie folgendermaßen erzeugen:
>>> random.gauss(0, 1)
1.4999823501567913
Dabei werden Erwartungswert (μ) und Standardabweichung (σ) als Parameter übergeben.
26.2.4 Zufallsgesteuerte Operationen auf Sequenzen 

Das Modul random enthält einige Funktionen, die zufallsgesteuerte Operationen auf Sequenzen durchführen, darunter die Funktion choice, die ein zufälliges Element der übergebenen nicht-leeren Sequenz zurückgibt:
>>> random.choice([1,2,3,4,5])
5
>>> random.choice([1,2,3,4,5])
2
>>> random.choice(["A", "B", "C"])
'B'
Analog zu choice kann choices verwendet werden, um k zufällig gewählte Elemente aus der übergebenen Sequenz zu erhalten:
>>> random.choices(range(100), k=4)
[76, 41, 39, 5]
Die Funktion sample bekommt eine Sequenz population und eine ganze Zahl k als Parameter übergeben. Das Ergebnis ist eine neue Liste mit k zufällig gewählten Elementen aus population. Auf diese Weise könnte beispielsweise eine gewisse Anzahl von Gewinnern aus einer Liste von Lotterieteilnehmern gezogen werden. Beachten Sie, dass auch die Reihenfolge der erzeugten Liste zufällig ist und dass mehrfach in population vorkommende Werte auch mehrfach gezogen werden können.
>>> pop = [1,2,3,4,5,6,7,8,9,10]
>>> random.sample(pop, 3)
[7, 8, 5]
>>> random.sample(pop, 3)
[5, 9, 7]
Die Funktion sample kann insbesondere auch in Kombination mit der Built-in Function range verwendet werden:
>>> random.sample(range(10000000), 3)
[4571575, 2648561, 2009814]
Die Funktion shuffle bringt die Elemente der Sequenz x in eine zufällige Reihenfolge. Beachten Sie, dass diese Funktion nicht seiteneffektfrei ist, sondern die übergebene Sequenz verändert wird. Aus diesem Grund dürfen für x auch nur Instanzen veränderlicher sequenzieller Datentypen übergeben werden.
>>> l = [1,2,3,"A","B"]
>>> random.shuffle(l)
>>> l
[1, 'B', 2, 'A', 3]
26.2.5 SystemRandom([seed]) 

Das Modul random enthält zusätzlich zu den oben erläuterten Funktionen eine Klasse namens SystemRandom, die es ermöglicht, den Zufallszahlengenerator des Betriebssystems anstelle des Python-eigenen zu verwenden. Diese Klasse existiert nicht auf allen, aber auf den gängigsten Betriebssystemen.
Beim Instanziieren der Klasse kann eine Zahl oder Instanz zur Initialisierung des Zufallszahlengenerators übergeben werden. Danach lässt sich die Klasse SystemRandom wie das Modul random verwenden, da sie die meisten im Modul enthaltenen Funktionen als Methode implementiert.
Beachten Sie jedoch, dass nicht der komplette Funktionsumfang von random in SystemRandom zur Verfügung steht. So wird ein Aufruf der Methode seed ignoriert, während Aufrufe der Methoden getstate und setstate eine NotImplementedError-Exception werfen.
>>> sr = random.SystemRandom()
>>> sr.randint(1, 10)
9