Что такое модуль random
Модуль random — это часть стандартной библиотеки Python с функциями для случайных чисел и случайного выбора. Устанавливать ничего не нужно: модуль есть в каждой версии Python 3, его достаточно подключить командой import.
import random
print(random.randint(1, 6))
print(random.choice(["камень", "ножницы", "бумага"]))
Каждый запуск этой программы печатает разные результаты: то 4 и «бумага», то 1 и «камень». Именно это и нужно играм: если бы компьютер всегда выбирал одно и то же, играть с ним было бы неинтересно. Модулем называют файл с готовым кодом, который можно подключить к своей программе, — вроде набора деталей, которые не надо собирать самому.
Числа, которые выдаёт random, на самом деле не совсем случайные. Их вычисляет формула-генератор, и официальная документация Python прямо называет их псевдослучайными: модуль использует генератор под названием «вихрь Мерсенна»[1]. Для игр, рисунков и учебных опытов такой случайности более чем достаточно. Описание всех функций модуля публикует Python Software Foundation в документации к стандартной библиотеке. А вот для паролей и шифрования документация random использовать не рекомендует — об этом ниже.
Как подключить модуль random
Подключить модуль можно 2 способами: import random подключает его целиком, и тогда функции вызывают через точку, а from random import randint берёт только нужную функцию, и её вызывают без префикса.
import random
x = random.randint(1, 100)
from random import choice, shuffle
color = choice(["красный", "синий", "жёлтый"])
print(x, color)
Первый вариант понятнее новичку: по записи random.randint сразу видно, откуда взялась функция. Второй короче, но легко забыть, что choice — не ваша функция, а из модуля. Строку с import пишут в самом начале файла — так советует руководство PEP 8[2]. Если забыть import, Python остановится с ошибкой NameError: name 'random' is not defined. Не стоит называть собственный файл random.py: Python найдёт его раньше стандартного модуля, и random.randint перестанет работать.
randint и randrange: случайные целые числа
Функция randint(a, b) возвращает случайное целое число от a до b, причём обе границы входят: randint(1, 6) может дать и 1, и 6. Функция randrange устроена как range — правая граница в ней не входит, зато можно задать шаг.
import random
dice = random.randint(1, 6)
percent = random.randint(0, 100)
even = random.randrange(0, 101, 2)
digit = random.randrange(10)
print(dice, percent, even, digit)
| Запись | Какие числа возможны | Где пригодится |
randint(1, 6) | 1, 2, 3, 4, 5, 6 | Игральный кубик |
randint(0, 1) | 0 или 1 | Монетка, да или нет |
randrange(10) | 0…9 | Случайная цифра |
randrange(0, 101, 2) | 0, 2, 4, …, 100 | Случайное чётное число |
randrange(5, 50, 5) | 5, 10, …, 45 | Числа, кратные 5 |
Разница в правой границе — главная ловушка модуля random. У randint она включена, у randrange и range — нет. Если в игре «угадай число от 1 до 100» написать randrange(1, 100), число 100 никогда не загадается. Проверить это легко: запустите генерацию тысячу раз и посмотрите на максимум.
choice, shuffle и sample: работа со списками
Для списков в модуле random есть 3 функции: choice выбирает один случайный элемент, shuffle перемешивает весь список на месте, а sample возвращает несколько разных элементов без повторов.
import random
team = ["Аня", "Боря", "Вика", "Гоша", "Даша"]
print("Капитан:", random.choice(team))
random.shuffle(team)
print("Порядок выступлений:", team)
print("Дежурные:", random.sample(team, 2))
print("Случайная буква:", random.choice("абвгд"))
choice работает с любой последовательностью, в том числе со строкой: так можно выбрать случайную букву. shuffle ничего не возвращает и меняет сам список, поэтому запись team = random.shuffle(team) положит в переменную None. Если исходный порядок нужно сохранить, сначала сделайте копию: mixed = team[:], а потом перемешайте её. sample(team, 2) гарантирует, что два дежурных будут разными людьми, а два вызова choice подряд могут выбрать одного и того же. Как устроены списки и их копии, разобрано в уроке про списки в Python.
random() и uniform: случайные дробные числа
Функция random() без аргументов возвращает дробное число от 0 до 1, причём 1 не входит, а uniform(a, b) — дробное число между a и b. Дробные случайные числа нужны для вероятностей и плавных движений.
import random
p = random.random()
print(round(p, 3))
if random.random() < 0.3:
print("Выпал бонус! Шанс был 30%")
temperature = random.uniform(18.0, 25.0)
print("Температура:", round(temperature, 1))
Приём if random.random() < 0.3 — это способ сказать «с вероятностью 30%». Число от 0 до 1 падает в отрезок от 0 до 0,3 примерно в трёх случаях из десяти. Так в играх задают шанс выпадения редкого предмета или промаха. Для вывода дробей используйте round или f-строки с форматом, иначе на экране окажется 16 знаков после запятой.
seed: повторяемая случайность
Функция seed(n) задаёт начальное значение генератора: после одинакового seed программа выдаёт одну и ту же последовательность случайных чисел. Это нужно для отладки и проверки — чтобы ошибку можно было воспроизвести.
import random
random.seed(42)
print(random.randint(1, 100), random.randint(1, 100))
random.seed(42)
print(random.randint(1, 100), random.randint(1, 100))
Обе строки вывода совпадут: генератор начал с одной точки и прошёл тот же путь. Именно так поведение seed описано в официальной документации модуля. Без seed начальное значение берётся из системного времени или других источников, поэтому каждый запуск разный. Важная оговорка: одинаковый seed гарантирует одинаковые числа только в одном и том же интерпретаторе. Редактор на нашем сайте работает на Skulpt, а не на стандартном Python, поэтому при том же seed числа могут отличаться от тех, что покажет IDLE на компьютере. О возможностях и ограничениях редактора — на странице про онлайн-редактор Python.
Игры на модуле random
Почти каждая учебная игра на Python начинается со случайности: компьютер загадывает число, бросает кубик или выбирает ход. Вот 3 короткие заготовки, которые легко развить в полноценные игры.
import random
secret = random.randint(1, 20)
print("Я загадал число от 1 до 20")
move = random.choice(["камень", "ножницы", "бумага"])
print("Мой ход:", move)
total = 0
for i in range(3):
total += random.randint(1, 6)
print("Сумма трёх кубиков:", total)
Первая строка — основа игры «Угадай число»: дальше нужен цикл с input и подсказками «больше» и «меньше», пошаговый разбор есть в статье об игре «Угадай число». Вторая — ход компьютера в «Камень, ножницы, бумага». Третья — бросок нескольких кубиков для настольной игры. Любая такая игра становится интереснее, когда в ней есть счёт, жизни и уровни, а случайность лишь добавляет неожиданность. Случайность можно добавить и в рисунки: если черепашке задавать случайный цвет и угол, каждый запуск рисует новый узор. Идея рисовать с помощью программы и исследовать, что получится, восходит к языку Logo, который описал Сеймур Пейперт[3].
Симуляции: проверяем вероятность опытом
Симуляция — это опыт, который программа повторяет тысячи раз, чтобы увидеть закономерность. С модулем random можно за секунду подбросить монетку 10 000 раз и проверить, правда ли орлов выпадает примерно половина.
import random
heads = 0
for i in range(10000):
if random.randint(0, 1) == 1:
heads += 1
print("Орлов:", heads, "из 10000")
print("Доля:", round(heads / 10000, 2))
Ответ каждый раз немного разный, но доля почти всегда будет близка к 0,5. Попробуйте уменьшить число бросков до 10: разброс станет гораздо больше. Это и есть закон больших чисел в действии — его проходят в курсе теории вероятностей, а здесь его можно увидеть своими глазами. Таким же способом проверяют, какая сумма двух кубиков выпадает чаще всего: заведите список счётчиков на 13 ячеек и считайте суммы.
Как пробовать примеры в редакторе
Чтобы проверить любой пример, вставьте его в редактор вверху страницы и нажмите «▶ Запустить» или Ctrl+Enter: результат появится справа в окне «Вывод». Кнопка «Сбросить» возвращает стартовую программу.
Запустите стартовый код несколько раз подряд — кубики, питомец дня и монетка будут меняться. Затем поэкспериментируйте: замените randint(1, 6) на randint(1, 20), добавьте в список своих питомцев, вставьте random.seed(7) после import и убедитесь, что результат перестал меняться. Если программа содержит input(), под выводом откроется поле ввода. Черновик сохраняется в браузере, поэтому изменения не пропадут после перезагрузки страницы. Если появится ошибка, редактор покажет сообщение и подсказку на русском.
Когда модуль random не подходит
Модуль random не подходит там, где случайность должна быть непредсказуемой для злоумышленника или где результат обязан быть одинаковым при каждом запуске. В этих 4 случаях нужен другой подход.
- Пароль из 12 символов или секретный код. Документация Python прямо предупреждает: для безопасности есть модуль secrets, а random предсказуем.
- Автопроверка задачи с 5 тестами. Тест не может ожидать конкретное случайное число — либо задайте seed, либо проверяйте диапазон.
- Честная лотерея на 100 участников с призами. Результат должен быть проверяемым и прозрачным, а не зависеть от программы на одном компьютере.
- Обход всех 6 вариантов по очереди. Если нужно перебрать всё, используйте цикл for, а не надейтесь, что случай выберет каждый вариант.
«Компьютер умеет выдавать по-настоящему случайные числа обычной функцией». Это миф: random выдаёт псевдослучайные числа по формуле, и при одинаковом seed последовательность повторяется.
«Если монетка 5 раз подряд показала орла, в 6-й раз решка выпадет с большей вероятностью». Это не подтверждается: броски независимы, и шанс каждый раз остаётся 1 к 2 — симуляция выше это показывает.
Чего делать нельзя
Нельзя путать границы: randint(1, 6) включает 6, а randrange(1, 6) — нет. Остальные правила помогают избежать странного поведения программ со случайностью.
- Нельзя называть свой файл
random.py— Python подключит его вместо стандартного модуля. - Не следует присваивать результат shuffle:
a = random.shuffle(a)превращает список в None. - Не стоит генерировать пароли этим модулем — для этого существует модуль secrets.
- Не допускается вызывать
choiceдля пустого списка — будет ошибка IndexError. - Нельзя писать тесты, которые ждут конкретного случайного значения без seed: они будут то проходить, то падать.
- Не стоит вызывать
seedс одним и тем же числом внутри цикла — каждый шаг будет выдавать одно и то же «случайное» число.
Источники
[1] The Python Tutorial (официальная документация Python 3). Python Software Foundation.
[2] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
[3] Papert S. Mindstorms: Children, Computers, and Powerful Ideas. New York: Basic Books, 1980.
Вопросы и ответы
Почему при каждом запуске результат разный?
Если seed не задан, генератор берёт начальное значение из системных источников, например времени. Поэтому последовательность каждый раз начинается с новой точки.
Как получить случайное число от 1 до 10 включительно?
Используйте randint(1, 10) — обе границы входят. Аналог через randrange — randrange(1, 11).
Чем выбор одного элемента отличается от выборки?
Первая функция возвращает один элемент, вторая — список из нескольких разных элементов без повторов. Повторный одиночный выбор может вернуть тот же элемент.
Можно ли выбрать случайный цвет для черепашки?
Да: составьте список названий цветов и передайте выбранное название в команду color. Каждый запуск даст новый рисунок.
Работает ли случайность в Scratch?
Да, в Scratch для этого есть блок «выдать случайное от 1 до 10» в разделе «Операторы». Он, как и аналог в Python, включает обе границы.
Сколько знаков после запятой у random()?
Число хранится с точностью около 16 знаков. Для вывода его обычно округляют функцией round до 2–3 знаков.