В процессе программирования на Python может понадобиться случайное число. О том, как создать собственный простейший генератор псевдослучайных чисел и пойдет разговор в этой статье. Будут рассмотрены некоторые популярные методы и функции, которые включены в модуль random для Python 3 и позволяют получать значения случайным образом (randomly).
В качестве лирического отступления следует сказать, что, согласно специфике внутреннего состояния генератора, модуль для Python под названием random позволяет сгенерировать не случайный, а псевдослучайный элемент, то есть значения и их последовательности формируются на основе формулы. Раз последовательность зависит от нескольких параметров, она не является случайной в полном смысле этого слова. Если нужна истинная случайность, генерация может основываться, к примеру, на принципах квантовой механики, однако на практике это слишком дорого и сложно, да и не всегда экономически целесообразно, ведь для многих задач программирования вполне подойдут и псевдослучайные генераторы (если речь идет не про онлайн-казино). Вдобавок к этому, случайность (randomness) — вещь капризная, поэтому, как тут не вспомнить прекрасное высказывание американского математика Роберта Кавью:
Также на ум приходит еще одно интересное высказывание, но уже от выдуманного персонажа и с некоторым уклоном в философию:
Применение random в Python
В языке программирования «Пайтон» модуль random позволяет реализовывать генератор псевдослучайных чисел для разных распределений, куда входят как целые (integers), так и вещественные числа, то есть числа с плавающей запятой.
Общий список методов, поддерживаемых модулем random, можно посмотреть в таблице ниже. Тут стоит обратить внимание, что возврат значений может осуществляться на основе разных распределений (распределение Парето, распределение Вейбулла и т. д.), выбор которых зависит от области применения генератора случайных чисел (статистика, теория вероятности).
Но мы не будем углубляться в распределения, а рассмотрим самые простые методы. А так как разглядывать их в таблице совершенно неинтересно, давайте попрактикуемся и выясним, как может быть использован тот или иной метод в деле.
Но прежде чем это сделать и иметь возможность полноценно использовать модуль, его надо импортировать. Делается это предельно просто: нужно прописать в начале кода import random
.
random.random
У модуля random есть одноименный метод-тезка — функция random. Она возвращает случайное число в диапазоне 0 — 1.0:
import random
print("Выводим случайное число с помощью random.random():")
print(random.random())
Если вы скопируете этот простейший код себе (можно использовать любой онлайн-компилятор), вы получите другое число.
Также вывести можно не одно, а, к примеру, три (three) числа (используется for i in range), причем прекрасным решением будет ограничить вывод до двух знаков после запятой (за это отвечает ‘%.2f’):
import random
print("Выводим 3 случайных числа; не более 2 знаков после запятой:")
print(['%.2f' % random.random() for i in range(3)])
random.seed
Метод seed может показаться более сложным для понимания. Фишка в том, что, как уже было сказано выше, используется генератор псевдослучайных чисел, то есть выдача этих чисел происходит в соответствии с алгоритмом. Алгоритм вычисляет значение на основе другого числа, но это число берется не с потолка — оно вычисляется на основании текущего системного времени. В результате, если вы будете пробовать на своем компьютере один из кодов, рассмотренных выше, вы будете получать каждый раз новые числа.
Если же задействовать seed с одним и тем же параметром, то вычисление будет производиться на основании этого параметра. Итог — на выходе будут получаться одинаковые «случайные» значения. Возьмем для примера параметр 5 и сделаем так, чтобы метод отработал дважды:
import random
random.seed(5)
print(random.random())
random.seed(5)
print(random.random())
random.uniform
С uniform все проще: возвращается псевдослучайное вещественное число, находящееся в определенном диапазоне, который указывается разработчиком:
import random
print("Находим число с плавающей точкой в заданном диапазоне:")
print(random.uniform(5, 10))
random.randint
Randint в Python тоже позволяет вернуть псевдослучайное число в определенном диапазоне, но тут уже речь идет о целом значении (int, integer):
import random
print("Используем randint для генерации целого числа int из диапазона:")
print(random.randint(10, 20))
random.randrange
Следующий метод, называемый randrange, похож на предыдущий randint, но тут, кроме диапазона целых значений int, можно добавить еще и шаг выборки (в качестве третьего параметра):
import random
print("Генерируем случайное целое число в заданном диапазоне с шагом")
print(random.randrange(10, 100, 2))
Судя по результату ниже и в соответствии с выбранным диапазоном от 10 до 100, установив шаг 2, мы будем получать лишь четные значения:
random.choice
Применение choice позволяет вернуть элемент из какой-нибудь последовательности — это может быть список, строка, кортеж.
И это уже интереснее, т. к. напрашивается аналогия с броском игрального кубика:
import random
list = [1, 2, 3, 4, 5, 6]
print("Выборка одного элемента из списка с помощью choice:")
print(random.choice(list))
Ура, выпало шесть!
Проверьте, повезет ли так и вам. Но вообще, перечень может состоять из других цифр и даже слов.
Сыграйте в игру и попробуйте погадать, какой язык программирования вам лучше учить в Otus:
import random
list = ['Python','Java','C#','C++','PHP','C','JavaScript','Scala']
print("Какой язык программирования будешь учить?")
print(random.choice(list))
Sample и choices
Начиная с Python 3.6, появился метод choices. Его отличие в том, что он позволяет сделать выборку нескольких элементов из последовательности, а вот сколько именно будет значений, можно указать. В отличие от схожего метода sample, в choices возможно получение одинаковых цифр.
Вернемся к нашему виртуальному кубику. Вот работа sample:
import random
list = [1, 2, 3, 4, 5, 6]
print ("Выборка двух случайных значений:")
print (random.sample(list,2))
Все бы ничего, но этот метод будет постоянно выводить 2 разных значения. Если же мы захотим сымитировать бросок двух игральных кубиков, код придется менять, ведь в реальной жизни выкинуть дубль все-таки можно. Но зачем менять код, если есть choices? Он обеспечит вывод двух случайных значения из заданного диапазона, причем они могут повторяться. Это уже максимально приближено к реальному броску двух кубиков, причем профит достигается и за счет того, что объем кода не увеличивается. Ради интереса мы его даже уменьшили — оптимизировали (List превратился в l, да и лишний текст выкинули):
import random
l = [1,2,3,4,5,6]
print(random.choices(l, k=2))
Кстати, вот и дубль — результат равен [6, 6], причем всего лишь с 5-й попытки (можете поверить на слово):
Правда, тут нюанс: пришлось сменить онлайн-компилятор, так как на предыдущем компиляторе Python версии 3.6 не поддерживался.
random.shuffle
Функция с интересным названием shuffle может перемешивать последовательность, меняя местами значения (она не подходит для неизменяемых объектов). Здесь важна именно последовательность выпадения определенных значений, как в лото.
import random
list = [1,2,3,4,5,6,7,8,9,10]
random.shuffle(list)
print ("Крутим барабан и достаем шары наугад: ", list)
Остается добавить, что английское слово shuffle означает «тасовать, перемешивать». Как тут не вспомнить картежного шулера или лопату-шуфлю для перемешивания бетонного раствора. Но это так, для общего развития.
Успехов вам, друзья!