Module random de Python
Apprenez le module random de Python : nombres aléatoires, choix pondérés, mélange de séquences, graine de reproductibilité et aléatoire cryptographique.
Le module intégré random de Python génère des nombres pseudo-aléatoires et effectue des sélections aléatoires. Il repose sur l'algorithme Mersenne Twister, qui produit des séquences pseudo-aléatoires de haute qualité adaptées aux simulations, jeux, échantillonnages et tests — mais pas à des fins sensibles sur le plan de la sécurité, telles que la génération de mots de passe ou de clés cryptographiques. Ce chapitre couvre :
- La génération de flottants, d'entiers et de plages aléatoires
- La sélection d'éléments aléatoires :
choice,choices,sample - Le mélange de séquences en place avec
shuffle - L'initialisation pour des résultats reproductibles
- Les distributions continues :
uniform,gauss,triangular - Quand utiliser
secretsplutôt querandom
Aucune installation n'est nécessaire — import random suffit.
Importation du module
import randomTous les exemples ci-dessous supposent que cet import est disponible. Vous pouvez également importer des fonctions individuellement pour éviter le préfixe random., bien que ce préfixe permette d'identifier clairement la provenance de chaque fonction :
from random import randint, choice, shuffleGénération de flottants aléatoires
random()
random.random() renvoie un flottant dans [0.0, 1.0) — incluant 0.0 mais n'atteignant jamais 1.0.
import random
print(random.random()) # e.g. 0.6394267984578837
print(random.random()) # e.g. 0.025010755222666936La valeur change à chaque appel car le générateur fait avancer son état interne.
uniform(a, b)
random.uniform(a, b) renvoie un flottant N tel que a <= N <= b :
import random
random.seed(42)
print(random.uniform(1.5, 10.5)) # 7.254841186120954
print(random.uniform(-1.0, 1.0)) # e.g. -0.82 (some float in [-1, 1])Contrairement à random(), uniform vous permet de spécifier les deux bornes de la plage, et la borne supérieure peut être renvoyée.
Génération d'entiers aléatoires
randint(a, b)
random.randint(a, b) renvoie un entier aléatoire N tel que a <= N <= b. Les deux bornes sont incluses :
import random
random.seed(42)
die = random.randint(1, 6)
print(die) # 6C'est la façon la plus courante de simuler des lancers de dés, des tirages de cartes ou n'importe quelle plage d'entiers discrets.
randrange(start, stop[, step])
random.randrange imite range() de Python — stop est exclu et vous pouvez spécifier un pas :
import random
random.seed(42)
# Pick an even number from 0 to 98 (0, 2, 4, ..., 98)
print(random.randrange(0, 100, 2)) # e.g. a random even integer
# Pick a multiple of 5 from 0 to 95
random.seed(42)
print(random.randrange(0, 100, 5)) # 15Lorsque vous avez besoin d'entiers aléatoires dans une plage qui ne commence pas à 0 ou qui nécessite un pas, randrange est plus expressif que randint.
getrandbits(k)
random.getrandbits(k) renvoie un entier non négatif aléatoire avec exactement k bits aléatoires :
import random
random.seed(42)
print(random.getrandbits(8)) # 163 (an integer in 0..255)
print(random.getrandbits(16)) # an integer in 0..65535Cela est utile lorsque vous avez besoin d'entiers aléatoires plus grands que ceux obtenus avec randint, ou lorsque vous travaillez au niveau des bits.
Sélection dans des séquences
choice(seq)
random.choice(seq) sélectionne un élément au hasard dans une séquence non vide. Cela fonctionne avec les listes, les tuples et les chaînes de caractères :
import random
random.seed(42)
fruits = ['apple', 'banana', 'cherry']
print(random.choice(fruits)) # cherry
random.seed(42)
print(random.choice('ABCDE')) # A (picks one character)Si la séquence est vide, une IndexError est levée.
choices(population, weights=None, k=1)
random.choices sélectionne k éléments avec remise (le même élément peut apparaître plusieurs fois). Vous pouvez biaiser la sélection avec weights :
import random
colors = ['red', 'blue', 'green']
# Equal probability — each run may differ
print(random.choices(colors, k=3))
# e.g. ['blue', 'red', 'red']
# Weighted: green is 3× more likely than red, blue is 2×
random.seed(42)
print(random.choices(colors, weights=[1, 2, 3], k=4))
# ['green', 'red', 'blue', 'blue']choices renvoie toujours une liste, même lorsque k=1. L'argument weights est relatif — [1, 2, 3] donne la même distribution que [10, 20, 30].
sample(population, k)
random.sample sélectionne k éléments sans remise — chaque élément ne peut apparaître qu'une seule fois dans le résultat. La séquence d'origine n'est pas modifiée :
import random
random.seed(42)
# Pick 4 unique numbers from 0-9
print(random.sample(range(10), 4)) # [1, 0, 4, 9]
# Simulate a lottery: 6 unique numbers from 1-49
random.seed(7)
ticket = sorted(random.sample(range(1, 50), 6))
print(ticket) # [4, 5, 10, 21, 26, 42]Si k est supérieur à la taille de la population, random.sample lève une ValueError :
import random
try:
random.sample([1, 2, 3], 5)
except ValueError as e:
print(e) # Sample larger than population or is negativeComparaison rapide entre choices et sample :
choices | sample | |
|---|---|---|
| Remise | Oui | Non |
| Résultats en double | Possible | Jamais |
| Modifie l'original | Non | Non |
| Supporte les poids | Oui | Non (utiliser choices) |
Mélange de séquences
random.shuffle(seq) mélange la liste en place et renvoie None. La liste d'origine est modifiée :
import random
random.seed(42)
deck = [1, 2, 3, 4, 5]
random.shuffle(deck)
print(deck) # [4, 2, 3, 5, 1] (original list is modified)Si vous avez besoin d'une copie mélangée sans toucher à l'original, utilisez random.sample :
import random
random.seed(42)
original = [1, 2, 3, 4, 5]
shuffled = random.sample(original, len(original))
print(original) # [1, 2, 3, 4, 5] (unchanged)
print(shuffled) # [4, 2, 3, 5, 1]Initialisation pour des résultats reproductibles
Par défaut, le module random s'initialise à partir de l'heure système (ou os.urandom()), de sorte que chaque exécution produit des valeurs différentes. Appeler random.seed() avec une valeur fixe verrouille la séquence afin d'obtenir une sortie identique à chaque fois — indispensable pour le débogage, les tests unitaires et les simulations reproductibles :
import random
random.seed(42)
print(random.random()) # 0.6394267984578837
print(random.randint(1, 10)) # 1
print(random.choice(['a', 'b', 'c'])) # c
# Reset to the same seed — identical sequence
random.seed(42)
print(random.random()) # 0.6394267984578837 (same as before)
print(random.randint(1, 10)) # 1
print(random.choice(['a', 'b', 'c'])) # crandom.seed() accepte un entier, une chaîne de caractères, un flottant, des bytes ou None (qui réinitialise à partir du système). L'initialisation est une opération globale — elle affecte tous les appels suivants dans le même programme, il faut donc définir la graine une seule fois au début d'un bloc reproductible.
Génération de données de test reproductibles
import random
random.seed(999)
test_scores = [round(random.uniform(0, 100), 2) for _ in range(5)]
print(test_scores) # [78.13, 8.01, 87.25, 57.38, 49.06]Chaque exécution avec seed(999) produit exactement la même liste, ce qui est utile pour les tests unitaires qui vérifient des valeurs spécifiques.
Distributions continues
Le module random inclut plusieurs distributions de probabilité continues, utiles dans les simulations et la modélisation statistique.
uniform(a, b)
Déjà présenté plus haut — une distribution uniforme où chaque valeur dans [a, b] est équiprobable.
triangular(low, high, mode)
Renvoie un flottant selon une distribution triangulaire où mode est la valeur la plus fréquente :
import random
random.seed(42)
# Most values cluster near 5, between 0 and 10
t = random.triangular(0, 10, 5)
print(t) # 5.753983033817951Utile quand vous connaissez les valeurs minimale, maximale et la plus probable, mais pas la distribution exacte — courant dans l'estimation de projets et la modélisation des risques.
gauss(mu, sigma)
Renvoie un flottant selon une distribution gaussienne (normale) de moyenne mu et d'écart-type sigma :
import random
random.seed(42)
# Heights in cm: mean 170, std 10
heights = [round(random.gauss(170, 10), 1) for _ in range(5)]
print(heights) # [168.6, 168.3, 168.9, 177.0, 168.7]random.normalvariate(mu, sigma) est équivalent mais thread-safe ; utilisez normalvariate dans les programmes multi-threadés.
expovariate(lambd)
Renvoie un flottant selon une distribution exponentielle, où lambd est 1 / moyenne. Utile pour modéliser le temps entre des événements (par ex. arrivées de clients, paquets réseau) :
import random
random.seed(42)
# Mean inter-arrival time = 5 minutes; lambd = 1/5
wait = random.expovariate(1 / 5)
print(round(wait, 2)) # 5.1 (minutes until next arrival)Exemples pratiques
Simulation de 60 lancers de dés
import random
random.seed(42)
counts = {face: 0 for face in range(1, 7)}
for _ in range(60):
counts[random.randint(1, 6)] += 1
print(counts)
# {1: 15, 2: 10, 3: 8, 4: 7, 5: 10, 6: 10}Avec davantage de lancers, la distribution se rapproche de la probabilité théorique de 1/6 pour chaque face.
Constitution d'une équipe aléatoire
import random
random.seed(42)
players = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve', 'Frank']
random.shuffle(players)
team_a = players[:3]
team_b = players[3:]
print('Team A:', team_a)
print('Team B:', team_b)Mot de passe aléatoire simple
Pour les contextes non sécurisés (démonstrations, jetons éphémères), random.choices convient bien :
import random
import string
random.seed(42)
chars = string.ascii_letters + string.digits
password = ''.join(random.choices(chars, k=12))
print(password) # NbrnTP3fAbnFPour de vrais mots de passe ou jetons utilisateurs, utilisez plutôt le module secrets (voir ci-dessous).
Quand utiliser secrets plutôt que random
Le module random n'est pas cryptographiquement sécurisé. Un attaquant qui observe suffisamment de sorties peut prédire les valeurs futures. Pour tout ce qui est sensible en matière de sécurité, utilisez le module secrets (Python 3.6+), qui s'appuie sur la source d'aléatoire cryptographique du système d'exploitation :
import secrets
# Cryptographically secure random integer in [0, 100)
print(secrets.randbelow(100))
# Secure random token for a password-reset link (URL-safe base64)
token = secrets.token_urlsafe(32)
print(token) # e.g. 'gIg9XzExxFkHLAH9JCK8Zxb1aBEFZ...'
# Secure random hex string for an API key
api_key = secrets.token_hex(16)
print(api_key) # e.g. 'a3f1c2d4e5b6...'Règle générale : si vous générez des jetons, des identifiants de session, des mots de passe ou toute valeur qu'un adversaire ne doit pas pouvoir deviner, utilisez secrets. Utilisez random pour tout le reste (jeux, simulations, données de test, échantillonnage).
Référence rapide
| Fonction | Description | Renvoie |
|---|---|---|
random.random() | Flottant dans [0.0, 1.0) | float |
random.uniform(a, b) | Flottant dans [a, b] | float |
random.randint(a, b) | Entier dans [a, b] (bornes incluses) | int |
random.randrange(start, stop[, step]) | Entier de range(start, stop, step) | int |
random.getrandbits(k) | Entier non négatif avec k bits aléatoires | int |
random.choice(seq) | Un élément aléatoire | type de l'élément |
random.choices(pop, weights, k) | k éléments avec remise | list |
random.sample(pop, k) | k éléments sans remise | list |
random.shuffle(seq) | Mélange la liste en place | None |
random.seed(a) | Définit la graine aléatoire | None |
random.gauss(mu, sigma) | Variable gaussienne (normale) | float |
random.normalvariate(mu, sigma) | Variable normale (thread-safe) | float |
random.triangular(low, high, mode) | Variable de distribution triangulaire | float |
random.expovariate(lambd) | Variable de distribution exponentielle | float |
Chapitres associés
- Python Math — fonctions mathématiques et constantes
- Python Modules — comment importer et organiser les modules
- Python Numbers — types entier, flottant et complexe
- Python Lists — travailler avec des séquences ordonnées
- Python For Loops — itération pour générer des données aléatoires
- Python Try Except — gestion des erreurs comme
ValueErrordesample