random.md
1> **Источник:** https://python-all.ru/3.10/library/random.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`random`](https://python-all.ru/3.10/library/random.html#module-random) – Генерация псевдослучайных чисел89**Исходный код:** [Lib/random.py](https://python-all.ru/src/3.10/Lib/random.py)1011---1213Этот модуль реализует генераторы псевдослучайных чисел для различных распределений.1415Для целых чисел есть равномерный выбор из диапазона. Для последовательностей есть равномерный выбор случайного элемента, функция для генерации случайной перестановки списка на месте и функция для случайной выборки без возвращения.1617На вещественной прямой есть функции для вычисления равномерного, нормального (гауссовского), логнормального, отрицательного экспоненциального, гамма и бета распределений. Для генерации распределений углов доступно распределение фон Мизеса.1819Почти все функции модуля зависят от базовой функции [`random()`](https://python-all.ru/3.10/library/random.html#random.random), которая генерирует случайное число с плавающей запятой, равномерно распределённое в полуоткрытом диапазоне \[0.0, 1.0). Python использует вихрь Мерсенна в качестве основного генератора. Он выдаёт числа с плавающей запятой точностью 53 бита и имеет период 2\*\*19937-1. Базовая реализация на C быстра и потокобезопасна. Вихрь Мерсенна – один из наиболее тщательно протестированных генераторов случайных чисел. Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографии.2021Функции, предоставляемые этим модулем, на самом деле являются привязанными методами скрытого экземпляра класса [`random.Random`](https://python-all.ru/3.10/library/random.html#random.Random). Можно создать собственные экземпляры [`Random`](https://python-all.ru/3.10/library/random.html#random.Random), чтобы получить генераторы, не разделяющие состояние.2223Класс [`Random`](https://python-all.ru/3.10/library/random.html#random.Random) также можно наследовать, если требуется использовать другой базовый генератор собственной разработки: в этом случае необходимо переопределить методы `random()`, `seed()`, `getstate()` и `setstate()`. При необходимости новый генератор может предоставить метод `getrandbits()` – это позволяет [`randrange()`](https://python-all.ru/3.10/library/random.html#random.randrange) производить выборки из произвольно большого диапазона.2425Модуль [`random`](https://python-all.ru/3.10/library/random.html#module-random) также предоставляет класс [`SystemRandom`](https://python-all.ru/3.10/library/random.html#random.SystemRandom), который использует системную функцию [`os.urandom()`](https://python-all.ru/3.10/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой.2627> **Предупреждение**28>29> Псевдослучайные генераторы этого модуля не следует использовать для целей безопасности. Для безопасности или криптографического использования см. модуль [`secrets`](https://python-all.ru/3.10/library/secrets.html#module-secrets).3031> **См. также**32>33> М. Мацумото и Т. Нисимура, «Вихрь Мерсенна: 623-мерно равномерно распределенный генератор псевдослучайных чисел», ACM Transactions on Modeling and Computer Simulation том 8, № 1, январь, стр. 3–30, 1998.34>35> [Complementary-Multiply-with-Carry recipe](https://python-all.ru/3.10/library/random.html) для совместимого альтернативного генератора случайных чисел с длинным периодом и сравнительно простыми операциями обновления.3637## Учётные функции3839#### `random.seed(a=None, version=2)`4041Инициализирует генератор случайных чисел.4243Если *a* опущен или равен `None`, используется текущее системное время. Если источники случайности предоставляются операционной системой, они используются вместо системного времени (см. функцию [`os.urandom()`](https://python-all.ru/3.10/library/os.html#os.urandom) для получения подробной информации о доступности).4445Если *a* – целое число, оно используется напрямую.4647В версии 2 (по умолчанию) объект [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray) преобразуется в [`int`](https://python-all.ru/3.10/library/functions.html#int) и используются все его биты.4849В версии 1 (предназначенной для воспроизведения случайных последовательностей из старых версий Python) алгоритм для [`str`](https://python-all.ru/3.10/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) генерирует более узкий диапазон начальных значений (семян).5051Изменено в версии 3.2: Переход на схему версии 2, которая использует все биты строкового начального значения.5253Устарело с версии 3.9: В будущем *seed* должен быть одним из следующих типов: *NoneType*, [`int`](https://python-all.ru/3.10/library/functions.html#int), [`float`](https://python-all.ru/3.10/library/functions.html#float), [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray).5455#### `random.getstate()`5657Возвращает объект, фиксирующий текущее внутреннее состояние генератора. Этот объект можно передать в [`setstate()`](https://python-all.ru/3.10/library/random.html#random.setstate) для восстановления состояния.5859#### `random.setstate(state)`6061*state* должен быть получен из предыдущего вызова [`getstate()`](https://python-all.ru/3.10/library/random.html#random.getstate), а [`setstate()`](https://python-all.ru/3.10/library/random.html#random.setstate) восстанавливает внутреннее состояние генератора в то, которое было на момент вызова [`getstate()`](https://python-all.ru/3.10/library/random.html#random.getstate).6263## Функции для байтов6465#### `random.randbytes(n)`6667Генерирует *n* случайных байтов.6869Этот метод не следует использовать для генерации токенов безопасности. Вместо этого используйте [`secrets.token_bytes()`](https://python-all.ru/3.10/library/secrets.html#secrets.token_bytes).7071Новое в версии 3.9.7273## Функции для целых чисел7475#### `random.randrange(stop)`7677#### `random.randrange(start, stop[, step])`7879Возвращает случайно выбранный элемент из `range(start, stop, step)`. Это равнозначно `choice(range(start, stop, step))`, но на самом деле не создаёт объект range.8081Шаблон позиционных аргументов совпадает с шаблоном [`range()`](https://python-all.ru/3.10/library/stdtypes.html#range). Именованные аргументы не следует использовать, поскольку функция может применить их неожиданным образом.8283Изменено в версии 3.2: [`randrange()`](https://python-all.ru/3.10/library/random.html#random.randrange) стала более совершенной в генерации равномерно распределённых значений. Ранее использовался подход, подобный `int(random()*n)`, который мог давать несколько неравномерные распределения.8485Устарело с версии 3.10: Автоматическое преобразование нецелых типов в эквивалентные целые числа устарело. Сейчас `randrange(10.0)` без потерь преобразуется в `randrange(10)`. В будущем это будет вызывать [`TypeError`](https://python-all.ru/3.10/library/exceptions.html#TypeError).8687Устарело с версии 3.10: Исключение, возникающее для нецелых значений, таких как `randrange(10.5)` или `randrange('10')`, будет изменено с [`ValueError`](https://python-all.ru/3.10/library/exceptions.html#ValueError) на [`TypeError`](https://python-all.ru/3.10/library/exceptions.html#TypeError).8889#### `random.randint(a, b)`9091Возвращает случайное целое *N* такое, что `a <= N <= b`. Псевдоним для `randrange(a, b+1)`.9293#### `random.getrandbits(k)`9495Возвращает неотрицательное целое число Python с *k* случайными битами. Этот метод предоставляется генератором MersenneTwister, и некоторые другие генераторы могут также предоставлять его как опциональную часть API. Когда доступен, [`getrandbits()`](https://python-all.ru/3.10/library/random.html#random.getrandbits) позволяет [`randrange()`](https://python-all.ru/3.10/library/random.html#random.randrange) обрабатывать произвольно большие диапазоны.9697Изменено в версии 3.9: Этот метод теперь принимает ноль для *k*.9899## Функции для последовательностей100101#### `random.choice(seq)`102103Возвращает случайный элемент из непустой последовательности *seq*. Если *seq* пуста, возбуждает [`IndexError`](https://python-all.ru/3.10/library/exceptions.html#IndexError).104105#### `random.choices(population, weights=None, *, cum_weights=None, k=1)`106107Возвращает список размера *k* из элементов, выбранных из *population* с возвращением. Если *population* пуста, возбуждает [`IndexError`](https://python-all.ru/3.10/library/exceptions.html#IndexError).108109Если задана последовательность *weights*, выборки производятся в соответствии с относительными весами. Альтернативно, если задана последовательность *cum\_weights*, выборки производятся по накопленным весам (возможно, вычисленным с помощью [`itertools.accumulate()`](https://python-all.ru/3.10/library/itertools.html#itertools.accumulate)). Например, относительные веса `[10, 5, 30, 5]` эквивалентны накопленным весам `[10, 15, 45, 50]`. Внутренне относительные веса преобразуются в накопленные перед выполнением выборок, поэтому передача накопленных весов экономит работу.110111Если не указаны ни *weights*, ни *cum\_weights*, выборки производятся с равной вероятностью. Если передана последовательность весов, её длина должна равняться длине последовательности *population*. Указание и *weights*, и *cum\_weights* приводит к [`TypeError`](https://python-all.ru/3.10/library/exceptions.html#TypeError).112113*weights* или *cum\_weights* могут использовать любой числовой тип, совместимый со значениями [`float`](https://python-all.ru/3.10/library/functions.html#float), возвращаемыми [`random()`](https://python-all.ru/3.10/library/random.html#module-random) (сюда входят целые числа, числа с плавающей запятой и дроби, но не десятичные числа). Предполагается, что веса неотрицательны и конечны. Если все веса равны нулю, возбуждается [`ValueError`](https://python-all.ru/3.10/library/exceptions.html#ValueError).114115Для заданного начального значения функция [`choices()`](https://python-all.ru/3.10/library/random.html#random.choices) с равными весами обычно порождает другую последовательность, чем повторные вызовы [`choice()`](https://python-all.ru/3.10/library/random.html#random.choice). Алгоритм, используемый [`choices()`](https://python-all.ru/3.10/library/random.html#random.choices), применяет арифметику с плавающей точкой для внутренней согласованности и скорости. Алгоритм, используемый [`choice()`](https://python-all.ru/3.10/library/random.html#random.choice), по умолчанию использует целочисленную арифметику с повторными выборками, чтобы избежать небольших смещений из-за ошибок округления.116117Новое в версии 3.6.118119Изменено в версии 3.9: Возбуждает [`ValueError`](https://python-all.ru/3.10/library/exceptions.html#ValueError), если все веса равны нулю.120121#### `random.shuffle(x[, random])`122123Перемешивает последовательность *x* на месте.124125Необязательный аргумент *random* – это функция без аргументов, возвращающая случайное число с плавающей запятой из диапазона \[0.0, 1.0); по умолчанию это функция [`random()`](https://python-all.ru/3.10/library/random.html#random.random).126127Чтобы перемешать неизменяемую последовательность и вернуть новый перемешанный список, используйте `sample(x, k=len(x))`.128129Обратите внимание, что даже для небольших `len(x)` общее число перестановок *x* может быстро превысить период большинства генераторов случайных чисел. Это означает, что большинство перестановок длинной последовательности никогда не могут быть сгенерированы. Например, последовательность длины 2080 – это самая длинная, которая умещается в период генератора случайных чисел Mersenne Twister.130131Устарело с версии 3.9, будет удалено в версии 3.11: Необязательный параметр *random*.132133#### `random.sample(population, k, *, counts=None)`134135Возвращает список длины *k* из уникальных элементов, выбранных из последовательности population или множества. Используется для случайной выборки без возвращения.136137Возвращает новый список, содержащий элементы из population, не изменяя исходную population. Результирующий список упорядочен по порядку выбора, так что все подсписки также будут корректными случайными выборками. Это позволяет разделить победителей розыгрыша (выборку) на обладателей главного и второго призов (подсписки).138139Элементы population не обязаны быть [хэшируемыми](https://python-all.ru/3.10/glossary.html#term-hashable) или уникальными. Если population содержит повторения, то каждое вхождение является возможным элементом выборки.140141Повторяющиеся элементы можно указывать по одному или с помощью необязательного параметра *counts*, передаваемого только по ключу. Например, `sample(['red', 'blue'], counts=[4, 2], k=5)` эквивалентно `sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)`.142143Чтобы выбрать выборку из диапазона целых чисел, используйте объект [`range()`](https://python-all.ru/3.10/library/stdtypes.html#range) в качестве аргумента. Это особенно быстро и эффективно по памяти при выборке из большой популяции: `sample(range(10000000), k=60)`.144145Если размер выборки превышает размер популяции, возбуждается исключение [`ValueError`](https://python-all.ru/3.10/library/exceptions.html#ValueError).146147Изменено в версии 3.9: Добавлен параметр *counts*.148149Устарело с версии 3.9: В будущем *population* должен быть последовательностью. Экземпляры [`set`](https://python-all.ru/3.10/library/stdtypes.html#set) больше не поддерживаются. Множество необходимо предварительно преобразовать в [`list`](https://python-all.ru/3.10/library/stdtypes.html#list) или [`tuple`](https://python-all.ru/3.10/library/stdtypes.html#tuple), желательно с детерминированным порядком, чтобы выборка была воспроизводимой.150151## Вещественные распределения152153Следующие функции генерируют конкретные вещественные распределения. Имена параметров функций соответствуют переменным в уравнении распределения, как принято в математической практике; большинство этих уравнений можно найти в любом учебнике по статистике.154155#### `random.random()`156157Возвращает следующее случайное число с плавающей запятой в диапазоне \[0.0, 1.0).158159#### `random.uniform(a, b)`160161Возвращает случайное число с плавающей точкой *N* такое, что `a <= N <= b` для `a <= b` и `b <= N <= a` для `b < a`.162163Конечное значение `b` может как входить, так и не входить в диапазон в зависимости от округления чисел с плавающей запятой в уравнении `a + (b-a) * random()`.164165#### `random.triangular(low, high, mode)`166167Возвращает случайное число с плавающей точкой *N* такое, что `low <= N <= high` и с заданной *модой* между этими границами. Границы *low* и *high* по умолчанию равны нулю и единице. Аргумент *mode* по умолчанию равен середине между границами, что даёт симметричное распределение.168169#### `random.betavariate(alpha, beta)`170171Бета-распределение. Условия на параметры: `alpha > 0` и `beta > 0`. Возвращаемые значения находятся в диапазоне от 0 до 1.172173#### `random.expovariate(lambd)`174175Экспоненциальное распределение. *lambd* – это 1.0, делённая на желаемое среднее. Оно должно быть ненулевым. (Параметр мог бы называться «lambda», но это зарезервированное слово в Python.) Возвращаемые значения находятся в диапазоне от 0 до положительной бесконечности, если *lambd* положительно, и от отрицательной бесконечности до 0, если *lambd* отрицательно.176177#### `random.gammavariate(alpha, beta)`178179Гамма-распределение. (*Не* гамма-функция!) Условия на параметры: `alpha > 0` и `beta > 0`.180181Функция плотности распределения вероятности:182183```python184 x ** (alpha - 1) * math.exp(-x / beta)185pdf(x) = --------------------------------------186 math.gamma(alpha) * beta ** alpha187```188189#### `random.gauss(mu, sigma)`190191Нормальное распределение, также называемое распределением Гаусса. *mu* – это среднее, а *sigma* – стандартное отклонение. Эта функция немного быстрее, чем [`normalvariate()`](https://python-all.ru/3.10/library/random.html#random.normalvariate), определённая ниже.192193Примечание о многопоточности: когда два потока одновременно вызывают эту функцию, они могут получить одно и то же возвращаемое значение. Этого можно избежать тремя способами: 1) Пусть каждый поток использует свой экземпляр генератора случайных чисел. 2) Установите блокировки вокруг всех вызовов. 3) Используйте более медленную, но потокобезопасную функцию [`normalvariate()`](https://python-all.ru/3.10/library/random.html#random.normalvariate).194195#### `random.lognormvariate(mu, sigma)`196197Логнормальное распределение. Если взять натуральный логарифм этого распределения, получится нормальное распределение со средним *mu* и стандартным отклонением *sigma*. *mu* может принимать любое значение, а *sigma* должна быть больше нуля.198199#### `random.normalvariate(mu, sigma)`200201Нормальное распределение. *mu* – это среднее, а *sigma* – стандартное отклонение.202203#### `random.vonmisesvariate(mu, kappa)`204205*mu* – это средний угол, выраженный в радианах от 0 до 2\**pi*, а *kappa* – параметр концентрации, который должен быть больше или равен нулю. Если *kappa* равен нулю, это распределение сводится к равномерному случайному углу в диапазоне от 0 до 2\**pi*.206207#### `random.paretovariate(alpha)`208209Распределение Парето. *alpha* – параметр формы.210211#### `random.weibullvariate(alpha, beta)`212213Распределение Вейбулла. *alpha* – параметр масштаба, а *beta* – параметр формы.214215## Альтернативный генератор216217#### `class random.Random([seed])`218219Класс, реализующий генератор псевдослучайных чисел по умолчанию, используемый модулем [`random`](https://python-all.ru/3.10/library/random.html#module-random).220221Устарело с версии 3.9: в будущем *seed* должен быть одним из следующих типов: `NoneType`, [`int`](https://python-all.ru/3.10/library/functions.html#int), [`float`](https://python-all.ru/3.10/library/functions.html#float), [`str`](https://python-all.ru/3.10/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray).222223#### `class random.SystemRandom([seed])`224225Класс, использующий функцию [`os.urandom()`](https://python-all.ru/3.10/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой. Доступен не на всех системах. Не зависит от состояния программного обеспечения, и последовательности невоспроизводимы. Соответственно, метод [`seed()`](https://python-all.ru/3.10/library/random.html#random.seed) не действует и игнорируется. Методы [`getstate()`](https://python-all.ru/3.10/library/random.html#random.getstate) и [`setstate()`](https://python-all.ru/3.10/library/random.html#random.setstate) вызывают [`NotImplementedError`](https://python-all.ru/3.10/library/exceptions.html#NotImplementedError) при вызове.226227## Примечания о воспроизводимости228229Иногда бывает полезно иметь возможность воспроизводить последовательности, выдаваемые генератором псевдослучайных чисел. При повторном использовании начального значения одна и та же последовательность должна воспроизводиться от запуска к запуску, если не запущено несколько потоков.230231Большинство алгоритмов и функций инициализации генератора модуля random могут меняться в разных версиях Python, но два аспекта гарантированно остаются неизменными:232233- Если будет добавлен новый метод инициализации, будет предложен обратно совместимый инициализатор.234- Метод `random()` генератора продолжит выдавать ту же последовательность, если совместимому инициализатору передать то же начальное значение.235236## Примеры237238Простые примеры:239240```python241>>> random() # Случайное число с плавающей точкой: 0.0 <= x < 1.02420.37444887175646646243244>>> uniform(2.5, 10.0) # Случайное число с плавающей точкой: 2.5 <= x <= 10.02453.1800146073117523246247>>> expovariate(1 / 5) # Интервал между поступлениями в среднем 5 секунд2485.148957571865031249250>>> randrange(10) # Целое число от 0 до 9 включительно2517252253>>> randrange(0, 101, 2) # Чётное целое число от 0 до 100 включительно25426255256>>> choice(['win', 'lose', 'draw']) # Один случайный элемент из последовательности257'draw'258259>>> deck = 'ace two three four'.split()260>>> shuffle(deck) # Перемешать список261>>> deck262['four', 'two', 'ace', 'three']263264>>> sample([10, 20, 30, 40, 50], k=4) # Четыре выборки без возвращения265[40, 10, 50, 30]266```267268Симуляции:269270```python271>>> # Шесть вращений колеса рулетки (взвешенная выборка с возвращением)272>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)273['red', 'green', 'black', 'black', 'red', 'black']274275>>> # Раздать 20 карт без возвращения из колоды276>>> # из 52 игральных карт и определить долю карт277>>> # со значением десять: десятка, валет, дама или король.278>>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20)279>>> dealt.count('tens') / 202800.15281282>>> # Оценить вероятность выпадения 5 или более орлов за 7 подбрасываний283>>> # несимметричной монеты, которая выпадает орлом в 60% случаев.284>>> def trial():285... return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5286...287>>> sum(trial() for i in range(10_000)) / 10_0002880.4169289290>>> # Вероятность того, что медиана 5 выборок окажется в двух средних квартилях291>>> def trial():292... return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500293...294>>> sum(trial() for i in range(10_000)) / 10_0002950.7958296```297298Пример [статистического бутстрепа](https://python-all.ru/3.10/library/random.html) с использованием повторной выборки с возвращением для оценки доверительного интервала для среднего значения выборки:299300```python301# https://www.thoughtco.com/example-of-bootstrapping-3126155302from statistics import fmean as mean303from random import choices304305data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]306means = sorted(mean(choices(data, k=len(data))) for i in range(100))307print(f'The sample mean of {mean(data):.1f} has a 90% confidence '308 f'interval from {means[5]:.1f} to {means[94]:.1f}')309```310311Пример [пермутационного теста с повторной выборкой](https://python-all.ru/3.10/library/random.html) для определения статистической значимости или [p-значения](https://python-all.ru/3.10/library/random.html) наблюдаемого различия между эффектами препарата и плацебо:312313```python314# Пример из книги "Statistics is Easy" Денниса Шаши и Манды Уилсон315from statistics import fmean as mean316from random import shuffle317318drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]319placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]320observed_diff = mean(drug) - mean(placebo)321322n = 10_000323count = 0324combined = drug + placebo325for i in range(n):326 shuffle(combined)327 new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])328 count += (new_diff >= observed_diff)329330print(f'{n} label reshufflings produced only {count} instances with a difference')331print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')332print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')333print(f'hypothesis that there is no difference between the drug and the placebo.')334```335336Моделирование времени поступления и обслуживания запросов для многоканальной очереди:337338```python339from heapq import heapify, heapreplace340from random import expovariate, gauss341from statistics import mean, quantiles342343average_arrival_interval = 5.6344average_service_time = 15.0345stdev_service_time = 3.5346num_servers = 3347348waits = []349arrival_time = 0.0350servers = [0.0] * num_servers # время, когда каждый сервер становится доступным351heapify(servers)352for i in range(1_000_000):353 arrival_time += expovariate(1.0 / average_arrival_interval)354 next_server_available = servers[0]355 wait = max(0.0, next_server_available - arrival_time)356 waits.append(wait)357 service_duration = max(0.0, gauss(average_service_time, stdev_service_time))358 service_completed = arrival_time + wait + service_duration359 heapreplace(servers, service_completed)360361print(f'Mean wait: {mean(waits):.1f} Max wait: {max(waits):.1f}')362print('Quartiles:', [round(q, 1) for q in quantiles(waits)])363```364365> **См. также**366>367> [Statistics for Hackers](https://python-all.ru/3.10/library/random.html) – видеоурок от [Jake Vanderplas](https://python-all.ru/3.10/library/random.html) по статистическому анализу, использующему всего несколько фундаментальных понятий, включая моделирование, выборку, перемешивание и кросс-валидацию.368>369> [Economics Simulation](https://python-all.ru/3.10/library/random.html) – симуляция рынка от [Peter Norvig](https://python-all.ru/3.10/library/random.html), демонстрирующая эффективное использование многих инструментов и распределений, предоставляемых этим модулем (gauss, uniform, sample, betavariate, choice, triangular и randrange).370>371> [A Concrete Introduction to Probability (using Python)](https://python-all.ru/3.10/library/random.html) – учебное пособие от [Peter Norvig](https://python-all.ru/3.10/library/random.html), охватывающее основы теории вероятностей, написание симуляций и выполнение анализа данных с помощью Python.372373## Рецепты374375По умолчанию [`random()`](https://python-all.ru/3.10/library/random.html#random.random) возвращает числа, кратные 2⁻⁵³, в диапазоне *0.0 ≤ x \< 1.0*. Все такие числа равномерно распределены и точно представимы как числа с плавающей запятой Python. Однако многие другие представимые числа с плавающей запятой в этом интервале не могут быть выбраны. Например, `0.05954861408025609` не является целым кратным 2⁻⁵³.376377Следующий рецепт использует другой подход. Все числа с плавающей запятой в интервале могут быть выбраны. Мантисса берётся из равномерного распределения целых чисел в диапазоне *2⁵² ≤ mantissa \< 2⁵³*. Показатель степени берётся из геометрического распределения, где показатели меньше *-53* встречаются вдвое реже, чем следующий больший показатель.378379```python380from random import Random381from math import ldexp382383class FullRandom(Random):384385 def random(self):386 mantissa = 0x10_0000_0000_0000 | self.getrandbits(52)387 exponent = -53388 x = 0389 while not x:390 x = self.getrandbits(32)391 exponent += x.bit_length() - 32392 return ldexp(mantissa, exponent)393```394395Все [вещественнозначные распределения](https://python-all.ru/3.10/library/random.html#real-valued-distributions) в классе будут использовать новый метод:396397```python398>>> fr = FullRandom()399>>> fr.random()4000.05954861408025609401>>> fr.expovariate(0.25)4028.87925541791544403```404405Этот рецепт концептуально эквивалентен алгоритму, который выбирает из всех чисел, кратных 2⁻¹⁰⁷⁴, в диапазоне *0.0 ≤ x \< 1.0*. Все такие числа равномерно распределены, но большинство приходится округлять вниз до ближайшего представимого числа с плавающей запятой Python. (Значение 2⁻¹⁰⁷⁴ – это наименьшее положительное ненормализованное число с плавающей запятой, равное `math.ulp(0.0)`.)406407> **См. также**408>409> [Generating Pseudo-random Floating-Point Values](https://python-all.ru/3.10/library/random.html) – статья Аллена Б. Дауни, описывающая способы генерации более мелкозернистых чисел с плавающей запятой, чем обычно генерирует [`random()`](https://python-all.ru/3.10/library/random.html#random.random).410