Модуль Random для генерации случайных чисел в Python

Этот модуль реализует генераторы псевдослучайных чисел под различные потребности.

  • Для целых чисел есть выбор одного из диапазона.
  • Для последовательностей — выбор случайного элемента, функция случайной сортировки списка и функция случайного выбора нескольких элементов из последовательности.
  • Есть функции для вычисления однородных, нормальных (Гауссовских), логнормальных, отрицательных экспоненциальных, гамма и бета распределений.
  • Для генерации распределений углов доступно распределение фон Мизеса.

Почти все функции модуля зависят от основной функции random(), которая генерирует случайным образом чисто с плавающей точкой(далее float) равномерно в полуоткрытом диапазоне [0.0, 1.0).

Python использует Mersenne Twister в качестве основного генератора. Он производит 53-битные точные float и имеет период 2**19937-1. Основная его реализация в C быстрая и многопоточная. Mersenne Twister один из наиболее широко протестированных генераторов случайных чисел. Однако, будучи полностью детерминированным, он подходит не для любых целей, особенно для криптографических.

Модуль random так же предоставляет класс SystemRandom. Этот класс использует системную функцию os.urandom() для генерации случайных чисел из источников, которые предоставляет операционная система.

Псевдослучайные генераторы этого модуля не должны использоваться в целях безопасности. Для обеспечения безопасности или для криптографического использования ознакомьтесь с модулем secrets.

Функции для целых чисел

random.randrange(stop)
random.randrange(start, stop[, step])
Возвращает случайно выбранный элемент из range(start, stop, step). Это эквивалентно choice(range(start, stop, step)), но не создает объект диапазона.

Шаблон позиционного аргумента совпадает с шаблоном range(). Аргументы не должны использоваться как ключевого слова(start, stop, step), потому что функция может использовать их неожиданными способами.

random.randint(a, b)
Возвращает случайное целое число N так, чтобы a <= N <= b.

Функции для последовательностей

random.choice(seq)
Возвращает случайный элемент из непустой последовательности seq. Если seq пуст, возникает ошибка IndexError.

random.choices(population, weights=None, *, cum_weights=None, k=1)
Возвращает список элементов размером k, выбранных из population с заменой. Если population пуст, возникает ошибка IndexError.

>>> random.choices(["яблоки", "бананы", "вишня"], weights = [10, 1, 1], k = 5)
['яблоки', 'вишня', 'яблоки', 'яблоки', 'яблоки']

Если задана последовательность weights, выбор производится в соответствии с относительным весом. В качестве альтернативы, если задана последовательность cum_weights, выбор производится в соответствии с совокупными весами (возможно, вычисляется с использованием itertools.accumulate()).

Например, относительный вес [10, 5, 30, 5] эквивалентны кумулятивному весу [10, 15, 45, 50]. Внутренне относительные веса преобразуются в кумулятивные перед выбором, поэтому поставка кумулятивного веса экономит время.

Если ни weights, ни cum_weights не указаны, выбор производится с равной вероятностью. Если задана последовательность веса, она должна быть такой же, как и последовательность population. TypeError возникает, если не правильно указан аргумент weights или cum_weights.

Weights или cum_weights могут использовать любой тип чисел, который взаимодействует со значением float, возвращаемым функцией random() (который включает целые числа, числа с плавающей точкой и фракции, но исключает десятичные числа).

random.shuffle(x[, random])
Перемешивает последовательность x на месте.
Необязательный аргумент random — функция 0-аргумента, возвращающая случайное значение float в [0.0, 1.0]; по умолчанию это функция random().

>>> fruits = ["яблоки", "бананы", "вишня"]
>>> random.shuffle(fruits)
>>> fruits
['бананы', 'вишня', 'яблоки']

Чтобы перемешать неизменяемую последовательность и вернуть новый перемешанный список, используйте sample(x, k=len(x)).

Обратите внимание, что даже для небольшого len(x) общее количество перестановок x может увеличиваться сильнее, чем период большинства генераторов случайных чисел.
Это означает, что большинство перестановок длинной последовательности никогда не могут быть выполнены. Например, последовательность длиной 2080 элементов является самой большой, которая может вписываться в период генератора случайных чисел «Мерсин Твистер».

random.sample(population, k)
Возвращает список длиной k из уникальных элементов, выбранных из последовательности или множества. Используется для случайной выборки без замены.

>>> random.sample([0, 1, 2, 3, 4, 5, 6], 3)
[5, 6, 4]

Это новый список, содержащий элементы из последовательности, оставляя исходную последовательности неизменной. Новый список находится в порядке выбора, так что все суб-срезы будут также случайными последовательностями.

Это позволяет победителям розыгрышей (при выборке) делиться на главный приз, второе место и далее.

Участники не должны быть hashable или уникальными. Если последовательность содержит повторы, то каждое вхождение является возможным выбором в выборке.

Что бы выбрать одно число из ряда чисел, используйте объект range() в качестве аргумента. Это простое решение для выборки из большой последовательности: sample(range(10000000), k=60).

Если размер выборки больше длины последовательности, возникает ошибка ValueError.

Функции управления генератором

random.seed(a=None, version=2)
Инициализирует (запускает) генератор случайных чисел.
Если a не задан или None, используется текущее системное время. Если источники случайности предоставляются операционной системой, они используются вместо системного времени (см. функцию os.urandom() для получения подробной информации).
Используется значение a, если оно int (целое число).

>>> random.seed(10)
>>> random.random()
0.5714025946899135

При version=2 (по умолчанию), объекты str, bytes, или bytearray преобразуются в int и все его биты используются.

При version=1 (для воспроизведения случайных последовательностей из более старых версий Python), алгоритм для str и bytes
вырабатывает более узкий диапазон посева.

random.getstate()
Возвращает объект, фиксирующий текущее внутреннее состояние генератора. Этот объект может быть передан в setstate() для возобновления состояния.

>>> random.getstate()
(3, (2910518045, 2919558713, 592432859, 1634426085,
....
2194693540, 2), None)

random.setstate(state)
state должен быть получен из предыдущего вызова
getstate(). И setstate() восстановит внутреннее состояние генератора до такого, которое было получено из вызова getstate().

random.getrandbits(k)
Возвращает Python int со случайными битами k. Этот метод поставляется вместе с генератором MersenneTwister, в то время как другие генераторы могут также предоставлять его как необязательную часть API.

При возможности, getrandbits() включает randrange() для обработки диапазонов величины.

Другие функции генерации распределений

Функциональные параметры появляются после соответствующих переменных в уравнении распределения, которые используются в общей математической практике; большинство этих уравнений можно найти в любом статистическом тексте.

random.random()
Возвращает случайное число с плавающей точкой в диапазоне [0.0, 1.0).

random.uniform(a, b)
Возвращает случайное число с плавающей точкой N таким образом, чтобы a <= N <= b для a <= b и b <= N <= a для b < a.

>>> random.uniform(2.5, 10.0)
2.611243345184153

Конечное значение b будет или не будет включено в диапазон в зависимости от округления float в уравнении a + (b-a) * random().

random.triangular(low, high, mode)
Возвращает случайное число с плавающей точкой N, так, что low <= N <= high и с указанным mode между этими границами. Границы low и high по умолчанию равны 0 и 1.

>>> random.triangular(20, 60, 30)
34.605051874664895

Аргумент mode по умолчанию совпадает с серединой между границами, предоставляя симметричное распределение.

random.betavariate(alpha, beta)
Бета-распределение. Условиями для аргументов являются alpha > 0 и beta > 0. Возвращаемые значения варьируются от 0 до 1.

>>> random.betavariate(5, 10)
0.33277653214797026

random.expovariate(lambd)
Экспоненциальное распределение. lambd равно 1.0, деленное на желаемое среднее значение. Оно должно быть отличным от нуля (Параметр будет называться «лямбда», но это зарезервированное слово в Python). Возвращаемые значения варьируются от 0 до положительной бесконечности, если lambd положительный, и от отрицательной бесконечности до 0, если lambd отрицателен.

>>> random.expovariate(1.5)
2.0299375769298558

random.gammavariate(alpha, beta)
Гамма-распределение (Не гамма-функция!). Условиями для параметров являются alpha > 0 и beta > 0.

>>> random.gammavariate(5, 10)
71.54713670428183

Функция распределения вероятности:

          x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) =  --------------------------------------
            math.gamma(alpha) * beta ** alpha

random.gauss(mu, sigma)
Гауссовское распределение. mu — среднее значение, а sigma — стандартное отклонение. Она немного быстрее, чем функция normalvariate(), обозначенная ниже.

random.lognormvariate(mu, sigma)
Нормальное распределение логарифма. Если вы берете натуральный логарифм этого распределения, вы получите нормальное распределение со средним mu и стандартным отклонением sigma. mu может иметь любое значение, а sigma должно быть больше нуля.

>>> random.lognormvariate(0, 0.5)
0.8067122423139358

random.normalvariate(mu, sigma)
Нормальное распределение. mu — среднее значение, а sigma — стандартное отклонение.

>>> random.normalvariate(100, 50)
138.00550761929435

random.vonmisesvariate(mu, kappa)
mu — средний угол, выраженный в радианах от 0 до 2pi, а kappa — параметр концентрации, который должен быть больше или равен нулю.

>>> random.vonmisesvariate(1, 4)
0.8597679422468718

Если kappa равен нулю, это распределение сводится к равномерному случайному углу в диапазоне от 0 до 2pi.

random.paretovariate(alpha)
Распределение Парето. alpha — параметр формы.

>>> random.paretovariate(3)
1.2256909386811103

random.weibullvariate(alpha, beta)
Распределение Вейбулла. alpha — параметр масштаба, а beta — параметр формы.

>>> random.weibullvariate(1, 1.5)
1.56960602898881

Альтернативный генератор

random.Random([seed])
Класс, реализующий генератор псевдослучайных чисел по умолчанию, используемый модулем случайных чисел.
Доступен с версии python 3.9: В будущем seed должен быть одного из типов: None, int, float, str, bytes или bytearray.

random.SystemRandom([seed])
Класс, который использует функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой. Не на всех OS доступен. Не полагается на состояние программного обеспечения, последовательности не воспроизводятся.

Следовательно метод seed() не имеет эффекта и игнорируется. При вызове методов getstate() и setstate() получите ошибку NotImplementedError.

Примеры и инструкции

Базовые примеры:

>>> fro random inport *
>>> random()                      # Случайное float:  0.0 <= x < 1.0
0.37444887175646646
>>> uniform(2.5, 10.0)         # Случайное float:  2.5 <= x < 10.0
3.1800146073117523
>>> expovariate(1 / 5)         # Интервал между прибытием в среднем 5 секунд
5.148957571865031
>>> randrange(10)               # Целое число от 0 до 9 включительно
7
>>> randrange(0, 101, 2)      # Четное целое число от 0 до 100 включительно
26
>>> choice(["победа", "поражение", "ничья"])  # Случайный элемент из последовательности
'ничья'
>>> deck = 'раз два три четыре'.split()
>>> shuffle(deck)                  # Перемешать список
>>> deck
["четыре", "два", "раз", "три"]
>>> sample([10, 20, 30, 40, 50], k=4)  # Четыре элемента без замены
[40, 10, 50, 30]

Симуляторы:

>>> # Шесть результатов рулетки (взвешенная выборка с заменой)
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']
>>> # Задействуйте 20 карт без замены колоды из 52 игральных карт
>>> # и определите долю карт с десятизначным значением
>>> # (десятка, валет, королева или король).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
0.15
>>> # Оцените вероятность получения 5 или более побед из 7 спинов
>>> # смещенной монеты, которая располагается наверху в 60% случаев.
>>> trial = lambda: choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
>>> sum(trial() for i in range(10000)) / 10000
0.4169
>>> # Вероятность медианы 5 образцов, находящихся в средних двух квартилях
>>> trial = lambda : 2500 <= sorted(choices(range(10000), k=5))[2]  < 7500
>>> sum(trial() for i in range(10000)) / 10000
0.7958

Тест на знание модуля Python Random

Как получить 3 случайных элемента из списка num_list
Какой код всегда вернет случайное число кратное 3 и не больше 100?
Как получить случайную букву из строки "аеуяыоию"?
С помощью какого метода можно получить случайное float число из диапазона, например: от 0.89 до 1.67
Каких элементов списка cars будет боле в результате выполнения этого кода:
cars = ["Ford",  "Volvo",  "BMW"]
print(random.choices(cars, weights = [10, 89, 1], k=15))

Подписывайтесь на канал в Дзене

Полезный контент для начинающих и опытных программистов в канале Лента Python разработчика — Как успевать больше, делать лучше и не потерять мотивацию.

Обучение Python и Data Science

Профессия Data Scientist

Профессия Data Scientist

11 520 5 760 ₽/мес.
Профессия Python-разработчик

Профессия Python-разработчик

7 820 3 910 ₽/мес.
Профессия Python Fullstack

Профессия Python Fullstack

7 820 3 910 ₽/мес.
Курс Аналитик данных с нуля

Курс Аналитик данных с нуля

6 500 3 900 ₽/мес.

Появились вопросы? Задайте на Яндекс.Кью

У сайта есть сообщество на Кью >> Python Q <<. Там я, эксперты и участники отвечаем на вопросы по python и программированию.