ПРАКТИКУМ PYTHON · ЗАНЯТИЕ 🎲
Модуль random
Зачем нужны случайные числа
Это справочная страница: задач здесь нет. Всё, что на ней написано, понадобится в проектах — кубики, магический шар и загаданное слово без случайных чисел не сделать.
Случайные числа нужны не только играм:
- игры — бросок кубика, перетасованная колода карт, случайная награда;
- имитационное моделирование — когда компьютер должен решить, как поведёт себя человек, животное или очередь в магазине;
- статистика — случайная выборка данных для анализа;
- безопасность — ключи шифрования начинаются со случайного числа.
Функции для работы со случайностью лежат в модуле random стандартной библиотеки, и его надо подключить:
import randomСлучайные числа
randint(a, b) возвращает случайное целое число из отрезка [a; b]. Обе границы включаются:
import random
num1 = random.randint(0, 17) # от 0 до 17 включительно
num2 = random.randint(-5, 5) # от -5 до 5 включительно
print(num1)
print(num2)Числа можно получать сколько угодно раз, и повторы среди них — обычное дело: каждый раз выбор делается заново.
import random
for _ in range(10):
print(random.randint(1, 100))randrange() принимает те же аргументы, что и range(), но возвращает не последовательность, а одно случайно выбранное из неё число:
random.randrange(10) # от 0 до 9
random.randrange(5, 10) # от 5 до 9
random.randrange(0, 101, 10) # одно из чисел 0, 10, 20, …, 100Разница между ними ровно в правой границе: у randint(0, 10) десятка может выпасть, у randrange(0, 10) — нет. Это тот же принцип, что и у range().
random() возвращает вещественное число от 0.0 до 1.0 (единица не включается) и не принимает аргументов, а uniform(a, b) — вещественное число из заданного промежутка:
import random
print(random.random()) # например, 0.7203244934421581
print(random.uniform(1.5, 17.3))Случайный выбор из списка
choice() возвращает один случайный элемент списка или строки:
import random
print(random.choice('BEEGEEK'))
print(random.choice([1, 2, 3, 4]))
print(random.choice(['a', 'b', 'c', 'd']))Результат
E
3
csample(последовательность, k) возвращает список из k случайных элементов — все разные:
import random
numbers = [2, 5, 8, 9, 12]
print(random.sample(numbers, 2))
print(random.sample(numbers, 5))Результат
[12, 5]
[12, 8, 9, 5, 2]Просить больше элементов, чем есть, нельзя: random.sample(numbers, 6) при пяти элементах останавливает программу — ValueError: Sample larger than population or is negative.
shuffle() перемешивает список на месте — как sort(), только наоборот:
import random
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
random.shuffle(numbers)
print(numbers)Результат
[4, 7, 8, 1, 2, 3, 6, 5]shuffle() ничего не возвращает — как и sort(). Писать numbers = random.shuffle(numbers) нельзя: список окажется пустым.
Почему числа не совсем случайные
Числа, которые выдаёт random, называют псевдослучайными: они вычисляются по формуле. Формуле нужно начальное значение — его модуль берёт из системных часов в момент подключения. Часы меняются каждую сотую долю секунды, поэтому при каждом запуске ряд получается новым.
Иногда нужен, наоборот, повторяемый ряд — например, чтобы отладить программу на одних и тех же данных. Тогда начальное значение задают сами:
import random
random.seed(17) # с этого зерна ряд будет одним и тем же
for _ in range(10):
print(random.randint(1, 100))Запустив такую программу дважды, вы получите одинаковые числа — и это не поломка, а именно то, о чём попросили.
Подключить модуль можно и так: from random import *. Тогда имя модуля и точку перед функциями писать не нужно: randint(1, 6) вместо random.randint(1, 6).
Три разобранные задачи
Задача 1. Профессор Тимур преподаёт вводный курс статистики и просит программу, имитирующую бросок двух игральных кубиков.
import random
print('Бросаем кубики...')
print('Значения граней:')
print(random.randint(1, 6))
print(random.randint(1, 6))Грани кубика — числа от 1 до 6 включительно, поэтому randint() подходит точно: обе границы входят.
Задача 2. Тот же профессор хочет бросать кубики несколько раз подряд — пока не надоест.
import random
again = 'д'
while again.lower() == 'д':
print('Бросаем кубики...')
print('Значения граней:')
print(random.randint(1, 6))
print(random.randint(1, 6))
again = input('Бросить кубики ещё раз? (д = да, н = нет): ')Сколько будет бросков, заранее неизвестно — значит, while. А lower() позволяет отвечать и «Д», и «д».
Задача 3. Нужен симулятор десяти подбрасываний монеты: каждый раз выпадает орёл или решка.
import random
for _ in range(10):
num = random.randint(0, 1)
if num == 0:
print('Орел')
else:
print('Решка')Здесь случайное число играет роль монеты: два исхода — два возможных значения. Тот же приём годится для любого выбора из нескольких вариантов: сгенерировать номер и разобрать его развилкой.
Есть и короче: print(random.choice(['Орел', 'Решка'])). Выбирайте тот вариант, который понятнее вам самим, — оба верны.


