Случайные выборки и генерация чисел: модуль random
Модуль random в Python: основные возможности и варианты использования
Наиболее эффективное решение для генерации случайного целого числа в заданном диапазоне — функция random.randint(a, b). Она возвращает равномерно распределённое целое N, удовлетворяющее условию a ≤ N ≤ b. Для выбора случайного элемента из последовательности оптимальна random.choice(seq).
import random
# Случайное целое от 1 до 6 (как бросок кубика)
dice = random.randint(1, 6)
print(dice)
# Случайный элемент из списка
colors = ['red', 'green', 'blue']
pick = random.choice(colors)
print(pick)Python module random (использовать модуль random)
Эти функции покрывают 80% повседневных задач. В остальных случаях применяются специализированные варианты, описанные ниже.
Как получить случайное число с плавающей точкой от 0 до 1?
Используется random.random(). Возвращает число в полуинтервале [0.0, 1.0).
import random
val = random.random()
print(val)Типичная ошибка:
Начинающие ошибочно полагают, что random.random() может вернуть 1.0. На практике она никогда не равна 1, что важно при масштабировании интервала (например, для получения [0, 10) нужно умножить на 10, тогда максимальное значение будет 9.999...).
Как получить случайное число с плавающей точкой в произвольном диапазоне?
Функция random.uniform(a, b) возвращает float в интервале [a, b] или [b, a] (если a > b). Распределение равномерное.
import random
temp = random.uniform(36.0, 37.5)
print(temp)Как выбрать несколько случайных элементов без повторений?
Используется random.sample(population, k). Гарантирует отсутствие дубликатов. Кидает ValueError, если k больше длины последовательности.
import random
deck = list(range(52))
hand = random.sample(deck, 5)
print(hand)Проблема:
Попытка использовать sample на множестве может привести к неожиданному порядку из-за неупорядоченности итерации. Рекомендуется передавать список или кортеж.
Как перемешать список на месте?
Функция random.shuffle(lst) изменяет исходный список случайным образом. Не работает с неизменяемыми типами (кортежами, строками). Для строк используйте ''.join(random.sample(s, len(s))).
import random
cards = ['A', 'K', 'Q', 'J']
random.shuffle(cards)
print(cards)Ошибка:
Многие пытаются передать в shuffle кортеж и получают TypeError. Помните: объект должен поддерживать присваивание по индексу.
Как сделать генерацию воспроизводимой?
Установите начальное состояние генератора с помощью random.seed(value). Одинаковое seed даёт одинаковую последовательность чисел.
import random
random.seed(42)
print(random.randint(1, 100)) # всегда 82
random.seed(42)
print(random.randint(1, 100)) # снова 82Типичная ошибка:
Вызов seed() внутри цикла может сбросить последовательность и привести к псевдослучайной серии с повторениями. Обычно достаточно вызвать один раз в начале программы.
Как сгенерировать случайное число по нормальному распределению?
Функция random.gauss(mu, sigma) или random.normalvariate(mu, sigma). Первая быстрее.
import random
height = random.gauss(170, 10)
print(round(height, 1))Как сгенерировать случайное число по экспоненциальному распределению?
random.expovariate(lambd) возвращает число с плотностью вероятности lambd * exp(-lambd * x). Положительное, если lambd > 0.
import random
wait = random.expovariate(1.5)
print(round(wait, 2))Расширенные примеры использования модуля random
Воспроизводимая выборка с seed и reset
import random
random.seed(123)
data = [random.randint(0, 9) for _ in range(5)]
print('Первая серия:', data) # [5, 2, 5, 5, 8]
random.seed(123)
data2 = [random.randint(0, 9) for _ in range(5)]
print('Вторая серия:', data2) # [5, 2, 5, 5, 8]Первая серия: [5, 2, 5, 5, 8] Вторая серия: [5, 2, 5, 5, 8]
Случайная строка фиксированной длины из букв и цифр
import random
import string
length = 8
chars = string.ascii_letters + string.digits
password = ''.join(random.choice(chars) for _ in range(length))
print(password)tH7kQ2xZ (пример)
Перемешивание с возвратом нового списка (без изменения исходного)
import random
original = [1, 2, 3, 4, 5]
shuffled = random.sample(original, len(original))
print('Original:', original)
print('Shuffled:', shuffled)Original: [1, 2, 3, 4, 5] Shuffled: [4, 1, 3, 5, 2]
Генерация случайных дат в заданном диапазоне
import random
from datetime import datetime, timedelta
start = datetime(2020, 1, 1)
end = datetime(2023, 12, 31)
delta = end - start
random_days = random.randint(0, delta.days)
random_date = start + timedelta(days=random_days)
print(random_date.strftime('%Y-%m-%d'))2022-07-19 (пример)
Случайное нормальное распределение с гистограммой (без matplotlib)
import random
bins = {}
for _ in range(1000):
val = int(random.gauss(100, 15)) # имитация IQ
bins[val] = bins.get(val, 0) + 1
for k in sorted(bins):
if k > 80 and k < 120:
print(f'{k}: {"#" * (bins[k] // 5)}')87: ## 88: ### ... (вывод не приводится полностью)
Использование random.choices с весами (выбор с заменой)
import random
items = ['камень', 'ножницы', 'бумага']
weights = [0.5, 0.3, 0.2] # камень выпадает чаще
result = random.choices(items, weights=weights, k=10)
print(result)['камень', 'камень', 'ножницы', 'бумага', 'камень', 'ножницы', 'камень', 'камень', 'ножницы', 'камень']
Случайный элемент с исключением (без выбора из чёрного списка)
import random
items = [1, 2, 3, 4, 5]
blacklist = {2, 4}
available = [x for x in items if x not in blacklist]
pick = random.choice(available)
print(pick)5 (пример)
Генерация случайного IP-адреса
import random
ip = '.'.join(str(random.randint(0, 255)) for _ in range(4))
print(ip)192.168.1.42 (пример)
Безопасный генератор паролей с использованием secrets (контекст)
Для криптостойкой случайности модуль random не подходит. Используйте secrets.
import secrets
import string
pwd = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(12))
print(pwd)F9kT3vQm7LxP (пример)