Модуль random — это встроенный модуль стандартной библиотеки Python для генерации псевдослучайных чисел: целых и вещественных, а также случайного выбора и перемешивания элементов последовательностей. Он не требует установки и подключается строкой import random.
Содержание
Разберу основные функции модуля (randint, random, uniform, choice, shuffle, sample) с воспроизводимыми примерами, покажу, как работает seed и почему одинаковый seed дает одинаковый результат, отдельно отмечу границу безопасности (для паролей и токенов нужен модуль secrets, а не random) и коротко покажу numpy для массивов.
Минимальный рабочий пример
Вот полный скрипт, который бросает игральный кубик три раза. Его можно скопировать и запустить как есть:
import random
random.seed(1) # фиксирую генератор, чтобы вывод повторялся
for i in range(3):
brosok = random.randint(1, 6)
print("Бросок", i + 1, "->", brosok)
Вывод:
Бросок 1 -> 2
Бросок 2 -> 5
Бросок 3 -> 1
Здесь random.randint(1, 6) возвращает случайное целое от 1 до 6 включительно, а random.seed(1) в начале делает результат воспроизводимым: при каждом запуске выпадет та же тройка. Уберите строку с seed — и числа будут меняться от запуска к запуску. Почему так — в разделе про псевдослучайность.
Основные функции модуля random
Модуль покрывает три задачи: сгенерировать число, выбрать элемент из набора и перемешать набор. Ниже — сводка самых используемых функций, а под таблицей — один общий пример с фактическим выводом.
| Функция | Что делает | Пример вызова |
|---|---|---|
random() |
вещественное в промежутке [0.0, 1.0) | random.random() |
randint(a, b) |
целое от a до b включительно | random.randint(1, 6) |
randrange(a, b) |
целое от a до b, но b не включается | random.randrange(1, 6) |
uniform(a, b) |
вещественное от a до b | random.uniform(10, 20) |
choice(seq) |
случайный элемент последовательности | random.choice(menu) |
choices(seq, k=n) |
n элементов с повторами, можно с весами | random.choices(menu, k=3) |
sample(seq, k=n) |
n разных элементов без повторов | random.sample(nums, 6) |
shuffle(seq) |
перемешивает список на месте | random.shuffle(deck) |
Общий пример под одним фиксированным seed — вывод воспроизводится дословно:
import random
random.seed(42) # фиксирую генератор -> вывод воспроизводим
print(random.random()) # вещественное в [0.0, 1.0)
print(random.randint(1, 6)) # целое от 1 до 6 включительно
print(random.uniform(10, 20)) # вещественное в [10, 20]
print(random.choice(["орел", "решка"]))
print(random.sample(range(1, 50), 6))
print(random.choices(["A", "B", "C"], weights=[5, 3, 2], k=4))
deck = ["туз", "король", "дама", "валет"]
random.shuffle(deck)
print(deck)
Вывод:
0.6394267984578837
1
17.41550499759833
орел
[15, 9, 7, 44, 35, 6]
['B', 'A', 'A', 'A']
['король', 'валет', 'дама', 'туз']
Различайте близкие вещи: random() дает дробь в [0.0, 1.0) без аргументов, uniform(a, b) — дробь в заданном промежутке. randint(a, b) включает верхнюю границу, а randrange(a, b) — нет (как срез списка). sample возвращает элементы без повторов, choices — с повторами и с необязательными весами. shuffle меняет список на месте и возвращает None — к этой типичной ошибке вернусь ниже.
Псевдослучайность и seed
Числа из модуля random не по-настоящему случайны, а псевдослучайны: их выдает детерминированный алгоритм (генератор Mersenne Twister), который по одному начальному числу — seed — разворачивает длинную последовательность, статистически похожую на случайную. Один и тот же seed всегда дает одну и ту же последовательность.
Если seed не задать явно, Python берет его из системного источника (по умолчанию — из данных ОС или текущего времени), поэтому при обычном запуске числа разные. Фиксированный seed нужен, когда результат важно повторить: тесты, отладка, воспроизводимые эксперименты, учебные примеры.
import random
random.seed(42)
run1 = [random.randint(1, 100) for _ in range(5)]
random.seed(42) # тот же seed -> та же последовательность
run2 = [random.randint(1, 100) for _ in range(5)]
print(run1)
print(run2)
print(run1 == run2)
Вывод:
[82, 15, 4, 95, 36]
[82, 15, 4, 95, 36]
True
Важная оговорка: seed делает вывод повторяемым, но не «более случайным». Он не улучшает качество чисел — только фиксирует стартовую точку.
random не годится для паролей и токенов
Здесь проходит граница безопасности. Генератор random предсказуем: зная состояние или несколько подряд идущих значений, злоумышленник может восстановить остальные. Для генерации паролей, токенов, ключей, идентификаторов сессий и любых секретов используйте модуль secrets — он опирается на криптостойкий источник ОС.
import secrets
# случайный токен: 32 шестнадцатеричных символа
print(secrets.token_hex(16))
# случайный пароль из букв и цифр
import string
alphabet = string.ascii_letters + string.digits
password = "".join(secrets.choice(alphabet) for _ in range(12))
print(password)
Вывод здесь намеренно не привожу: он должен быть разным при каждом запуске (в этом и смысл). У secrets есть аналоги привычных функций: secrets.choice, secrets.randbelow(n), secrets.token_hex, secrets.token_urlsafe. Правило простое: развлечения, симуляции, перемешивание, игры — random; все, что защищает данные, — secrets.
numpy.random для массивов
Когда нужны не отдельные числа, а сразу массивы (машинное обучение, численные расчеты), удобнее сторонняя библиотека numpy — она генерирует целые массивы за один вызов и работает быстрее цикла на чистом Python. Современный способ — создать генератор через default_rng и передать ему seed:
import numpy as np
rng = np.random.default_rng(42) # свой seed, независимый от random
print(rng.integers(1, 7, size=5)) # 5 целых в диапазоне [1, 7)
print(rng.random(3)) # массив из 3 дробей в [0.0, 1.0)
Вывод:
[1 5 4 3 3]
[0.69736803 0.09417735 0.97562235]
Обратите внимание: numpy использует собственный генератор со своим seed, поэтому random.seed() на него не влияет и наоборот. Диапазон integers(1, 7) не включает 7 — как range и randrange.
Три частые ошибки
Ошибка 1: присвоить результат shuffle. Метод shuffle перемешивает список на месте и возвращает None, а не новый список.
import random
deck = [1, 2, 3, 4, 5]
result = random.shuffle(deck)
print(result) # None - а ждали перемешанный список
Вывод: None, при этом сам deck уже перемешан. Исправление — перемешать на месте, а список читать по имени; если нужен новый список без изменения исходного, взять sample:
random.shuffle(deck) # deck меняется на месте
new = random.sample(deck, len(deck)) # или так: копия без мутации
Ошибка 2: перепутать границы randint и randrange. randint(1, 3) может вернуть 3, а randrange(1, 3) — нет (верхняя граница исключается).
import random
random.seed(0)
print([random.randint(1, 3) for _ in range(8)]) # 3 встречается
random.seed(0)
print([random.randrange(1, 3) for _ in range(8)]) # только 1 и 2
Вывод:
[2, 2, 1, 2, 3, 2, 2, 2]
[2, 2, 1, 2, 2, 2, 2, 2]
Ошибка 3: запросить у sample больше элементов, чем есть. sample берет элементы без повторов, поэтому k не может превышать длину последовательности.
import random
random.sample([1, 2, 3], 5)
Вывод — исключение, а не «сколько получится»:
ValueError: Sample larger than population or is negative
Исправление — уменьшить k до размера набора либо взять choices, который допускает повторы: random.choices([1, 2, 3], k=5).
Выводы
- Модуль
randomвстроен в Python и подключается черезimport random; установка не нужна. - Базовые функции:
random()иuniform()для дробей,randint()иrandrange()для целых,choice()/choices()/sample()для выбора,shuffle()для перемешивания. - Числа псевдослучайны: одинаковый
seedдает одинаковую последовательность, что удобно для тестов и воспроизводимых примеров, но не делает числа «более случайными». - Для паролей, токенов и любых секретов
randomне подходит — он предсказуем; берите модульsecrets. - Для массивов чисел используйте
numpyс собственным генераторомdefault_rng(seed); он независим отrandom.
Где применяется / связь с практикой
Случайные числа нужны в играх (бросок кубика, раздача карт, поведение врагов), в симуляциях и методе Монте-Карло, в перемешивании выборок и разбиении данных на train/test, в инициализации весов нейросетей, в A/B-тестах и в генерации тестовых данных. Как только в задаче звучит «случайно выбрать», «перемешать» или «сгенерировать пример», за этим обычно стоит random.
Освойте тему на практике
Освоить Python с нуля, включая работу с числами, коллекциями и модулями стандартной библиотеки, можно на курсе python-basic в Otus. Посмотреть формат и уровень занятий, не оплачивая курс, помогут бесплатные вебинары — там разбирают конкретные задачи и отвечают на вопросы.
Смежные темы: Python и создание 2D-игры: что нужно знать разработчику, Как создать нейросеть с нуля: рабочий пример на Python.
FAQ
Как получить одно и то же случайное число каждый раз?
Задайте seed перед генерацией: random.seed(42). Тот же seed дает ту же последовательность вызовов. Чтобы снова получить исходный результат, сбросьте seed перед повторным блоком.
Как выбрать случайный элемент словаря?
Ключи и значения словаря напрямую в random.choice не передать — нужен список: random.choice(list(mydict)) вернет случайный ключ, а random.choice(list(mydict.values())) — случайное значение.
Чем random.choices отличается от random.sample?
sample возвращает разные элементы без повторов и падает, если запросить больше, чем есть. choices возвращает элементы с повторами (один и тот же может выпасть дважды) и поддерживает веса через аргумент weights.



