Случайные выборки и генерация чисел: модуль random

Раздел: Основы Python -> Стандартные и сторонние модули

Модуль 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 (пример)

Использовать модуль random - comments

En
Python module random (python)