Gérer le hasard avec la bibliothèque standard Python : random (choix, échantillonnage, mélange, reproductibilité)

Série 04 – Génération de nombres aléatoires et mélange de données

« Choisir un élément au hasard », « mélanger », « sélectionner plusieurs éléments sans répétition », « attribuer des probabilités différentes ». Ces opérations sont fréquemment requises dans les jeux, la génération de données de test, les simulations simples ou la division de jeux de données.

Truc de casino du magicien

Le module random de la bibliothèque standard Python permet de répondre à ces besoins avec un code concis. Il convient toutefois de noter que random n’est pas adapté aux applications nécessitant une sécurité cryptographique.


1. La nature « aléatoire » produite par random



random génère des pseudo‑nombres aléatoires (PRNG). Plutôt que des nombres réellement imprévisibles, il crée une séquence qui semble aléatoire à partir d’un état interne.

  • Avec le même état initial (seed), la séquence de résultats est identique.
  • Cela facilite le débogage et les expériences reproductibles.
  • En revanche, dans les scénarios où un attaquant peut prédire l’état, random n’est pas adapté (voir secrets plus loin).

2. Nombres aléatoires de base : générer des nombres

2.1 Nombre décimal entre 0 et 1 : random()

import random

x = random.random()
print(x)  # 0.0 <= x < 1.0

2.2 Plage d’entiers : randint(a, b) / randrange()

import random

print(random.randint(1, 6))   # 1~6 (inclus)
print(random.randrange(0, 10, 2))  # 0,2,4,6,8
  • randint(a, b) inclut les bornes a et b
  • randrange(start, stop, step) suit la règle de range (stop exclu)

2.3 Nombre décimal dans une plage : uniform(a, b)

import random

print(random.uniform(1.5, 3.5))

3. Sélection dans une collection : choix, échantillonnage, mélange



3.1 Choisir un élément : choice()

import random

items = ["rock", "paper", "scissors"]
print(random.choice(items))

3.2 Sélectionner plusieurs éléments sans répétition : sample()

import random

nums = list(range(1, 46))
picked = random.sample(nums, k=6)  # 6 sans répétition
print(picked)
  • sample() ne modifie pas l’original
  • Pas de répétition

3.3 Mélanger une liste : shuffle() (en place)

import random

deck = list(range(10))
random.shuffle(deck)
print(deck)
  • shuffle() modifie la liste in‑place.
  • Pour conserver l’original, utilisez sample() pour créer une copie mélangée.
import random

deck = list(range(10))
shuffled = random.sample(deck, k=len(deck))
print(deck)
print(shuffled)

4. Choix pondéré : choices()

La possibilité de pondérer les choix (par exemple, « fréquemment, rarement ») est utile pour créer des sélections avec des probabilités différentes.

import random

items = ["common", "rare", "legendary"]
weights = [85, 14, 1]  # proportions

result = random.choices(items, weights=weights, k=10)
print(result)
  • choices() autorise par défaut la répétition.
  • weights peut représenter des probabilités (0‑1) ou des proportions.

5. Reproduire les résultats : seed()

En utilisant la même graine (seed), la séquence de résultats est identique. Cela est utile pour les tests.

import random

random.seed(42)
print(random.randint(1, 100))
print(random.randint(1, 100))

Même si différentes fonctions du module random sont utilisées, la séquence des résultats reste déterminée.

Note : seed() affecte l’état global. Dans les projets de grande envergure, il est plus sûr de créer une instance random.Random() séparée.


6. Utiliser un RNG local au lieu de l’état global : random.Random()

Vous pouvez isoler l’état du RNG sans toucher l’état global.

import random

rng = random.Random(42)  # RNG local
print(rng.randint(1, 100))
print(rng.randint(1, 100))

Cette approche est particulièrement utile dans les bibliothèques ou lorsque plusieurs parties du code partagent le même module.


7. Nombres aléatoires pour la sécurité : secrets

Le module random génère des nombres prévisibles. Pour les jetons, codes d’authentification ou liens de réinitialisation, utilisez secrets.

import secrets

token = secrets.token_urlsafe(16)
print(token)
  • secrets est conçu pour générer des nombres à partir d’une source sécurisée du système.

8. Exemples de cas d’utilisation courants

8.1 Sélectionner un ou plusieurs éléments aléatoires d’une liste

import random

users = ["u1", "u2", "u3", "u4", "u5"]
print(random.choice(users))        # 1
print(random.sample(users, k=2))   # 2 sans répétition

8.2 Mélanger les données et extraire la première partie

import random

data = list(range(100))
random.shuffle(data)
train = data[:80]
test = data[80:]

8.3 Roulette simple pondérée

import random

prizes = ["A", "B", "C", "D"]
weights = [1, 3, 10, 86]  # D le plus fréquent
print(random.choices(prizes, weights=weights, k=1)[0])

9. Conclusion

Le module random regroupe les opérations de choix aléatoire dans une API compacte.

  • Choisir un élément : choice
  • Sélection sans répétition : sample
  • Mélanger : shuffle
  • Choix pondéré : choices
  • Reproductibilité : seed ou random.Random()
  • Nombres aléatoires sécurisés : secrets

Dans la prochaine partie, nous explorerons d’autres modules de la bibliothèque standard, comme statistics ou math, pour manipuler les nombres.


Articles connexes :