Part 7

Случайность

Этот раздел посвящен модулю random из стандартной библиотеки Python. Он содержит инструменты для генерации случайных чисел и другой функциональности, связанной со случайностью.

Разделы этой части материала содержат много ссылок на документацию стандартной библиотеки Python. Рекомендуем переходить по ссылкам, чтобы познакомиться с тем, как устроена документация.

Генерация случайного числа

Функция randint(a, b) возвращает случайное целое число между a и b включительно. Например, следующая программа работает как обычный кубик:

from random import randint

print("The result of the throw:", randint(1, 6))

Выполнение может вывести:

Пример вывода

The result of the throw: 4

Следующая программа бросает кубик десять раз:

from random import randint

for i in range(10):
    print("The result of the throw:", randint(1, 6))

Запуск кода выше может вывести

Пример вывода

The result of the throw: 5 The result of the throw: 4 The result of the throw: 3 The result of the throw: 2 The result of the throw: 3 The result of the throw: 4 The result of the throw: 6 The result of the throw: 4 The result of the throw: 4 The result of the throw: 3

Обратите внимание: стоит помнить, что функция randint работает немного иначе по сравнению, например, со срезами или функцией range, с которыми мы уже сталкивались. Вызов функции randint(1, 6) дает число от 1 до 6 включительно, а вызов функции range(1, 6) дает диапазон чисел от 1 до 5.

Другие функции для случайного выбора

Функция shuffle перемешивает любую структуру данных, переданную как аргумент, прямо на месте. Например, следующая программа перемешивает список слов:

from random import shuffle

words = ["atlas", "banana", "carrot"]
shuffle(words)
print(words)
Пример вывода

['banana', 'atlas', 'carrot']

Функция choice возвращает случайно выбранный элемент из структуры данных:

from random import choice

words = ["atlas", "banana", "carrot"]
print(choice(words))
Пример вывода

'carrot'

Лотерейные числа

Обычный пример для изучения случайности — лотерейные числа. Попробуем вытянуть несколько лотерейных чисел. В национальной лотерее Финляндии есть набор из 40 чисел, 7 из которых выбираются в каждом еженедельном розыгрыше.

Первая попытка вытянуть набор чисел могла бы выглядеть так:

from random import randint

for i in range(7):
    print(randint(1, 40))

Однако в долгосрочной перспективе это не сработает, потому что одно и то же число может появиться дважды в одном еженедельном розыгрыше из семи чисел. Нам нужен способ убедиться, что все вытянутые числа уникальны.

Один вариант — хранить вытянутые числа в списке и добавлять число только если его еще нет в списке. Это можно повторять, пока длина списка не станет равна семи:

from random import randint

weekly_draw = []
while len(weekly_draw) < 7:
    new_rnd = randint(1, 40)
    if new_rnd not in weekly_draw:
        weekly_draw.append(new_rnd)

print(weekly_draw)

Более компактный подход — использовать функцию shuffle:

from random import shuffle

number_pool = list(range(1, 41))
shuffle(number_pool)
weekly_draw = number_pool[0:7]
print(weekly_draw)

Идея здесь в том, что сначала мы создаем список доступных чисел от 1 до 40, как будто это шарики в лотерейной машине. Затем набор чисел перемешивается, и первые семь чисел выбираются для еженедельного розыгрыша. Это избавляет нас от необходимости писать цикл.

На самом деле модуль random содержит еще более простой способ выбирать лотерейные числа: функцию sample. Она возвращает случайную выборку указанного размера из заданной структуры данных:

from random import sample

number_pool = list(range(1, 41))
weekly_draw = sample(number_pool, 7)
print(weekly_draw)
Loading

Откуда берутся эти случайные числа?

Возможности модуля random основаны на алгоритме, который производит случайные числа на основе определенного начального значения и некоторых арифметических операций. Начальное значение часто называют зерном.

Зерно можно задать с помощью функции seed:

from random import randint, seed

seed(1337)
# this will always produce the same "random" number
print(randint(1, 100))

Если у нас есть функции, которые зависят от случайности, и мы задаем зерно, функция будет выдавать один и тот же результат при каждом выполнении. Результат может отличаться в разных версиях Python, но по сути при задании зерна случайность теряется. Например, это может быть полезно при тестировании программы.

Loading
Loading
Loading
Loading
Вы дошли до конца этого раздела! Перейти к следующему разделу:

Текущие баллы можно посмотреть в синем индикаторе в правом нижнем углу страницы.