Документация Python неофициальный перевод

random.md

583 строк · 45.1 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.14/library/random.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `random` – Генерация псевдослучайных чисел89**Исходный код:** [Lib/random.py](https://python-all.ru/src/3.14/Lib/random.py)1011---1213Этот модуль реализует генераторы псевдослучайных чисел для различных распределений.1415Для целых чисел есть равномерный выбор из диапазона. Для последовательностей есть равномерный выбор случайного элемента, функция для генерации случайной перестановки списка на месте и функция для случайной выборки без возвращения.1617На вещественной прямой есть функции для вычисления равномерного, нормального (гауссовского), логнормального, отрицательного экспоненциального, гамма и бета распределений. Для генерации распределений углов доступно распределение фон Мизеса.1819Почти все функции модуля зависят от базовой функции [`random()`](https://python-all.ru/3.14/library/random.html#random.random), которая генерирует случайное число с плавающей запятой, равномерно распределённое в полуоткрытом интервале `0.0 <= X < 1.0`. Python использует Вихрь Мерсенна в качестве основного генератора. Он производит числа с плавающей запятой точностью 53 бита и имеет период 2\*\*19937-1. Базовая реализация на C является быстрой и потокобезопасной. Вихрь Мерсенна – один из наиболее тщательно протестированных генераторов случайных чисел из существующих. Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографических целей.2021Функции, предоставляемые этим модулем, на самом деле являются привязанными методами скрытого экземпляра класса [`random.Random`](https://python-all.ru/3.14/library/random.html#random.Random). Можно создать собственные экземпляры [`Random`](https://python-all.ru/3.14/library/random.html#random.Random), чтобы получить генераторы, не разделяющие состояние.2223Класс [`Random`](https://python-all.ru/3.14/library/random.html#random.Random) также можно подклассифицировать, если требуется использовать другой базовый генератор собственного изобретения: см. документацию по этому классу для получения дополнительных сведений.2425Модуль `random` также предоставляет класс [`SystemRandom`](https://python-all.ru/3.14/library/random.html#random.SystemRandom), который использует системную функцию [`os.urandom()`](https://python-all.ru/3.14/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой.2627> **Предупреждение**28>29> Псевдослучайные генераторы этого модуля не следует использовать для целей безопасности. Для безопасности или криптографического использования см. модуль [`secrets`](https://python-all.ru/3.14/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.14/library/random.html) для совместимого альтернативного генератора случайных чисел с длинным периодом и сравнительно простыми операциями обновления.3637> **Примечание**38>39> Глобальный генератор случайных чисел и экземпляры [`Random`](https://python-all.ru/3.14/library/random.html#random.Random) являются потокобезопасными. Однако в сборке со свободной многопоточностью (free-threaded build) конкурентные вызовы глобального генератора или к одному и тому же экземпляру `Random` могут привести к конкуренции и низкой производительности. Рекомендуется использовать отдельные экземпляры `Random` для каждого потока.4041## Учётные функции4243#### `random.seed(a=None, version=2)`4445Инициализирует генератор случайных чисел.4647Если *a* опущен или равен `None`, используется текущее системное время. Если источники случайности предоставляются операционной системой, они используются вместо системного времени (см. функцию [`os.urandom()`](https://python-all.ru/3.14/library/os.html#os.urandom) для получения подробной информации о доступности).4849Если *a* является целым числом, используется его абсолютное значение.5051В версии 2 (по умолчанию) объект [`str`](https://python-all.ru/3.14/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray) преобразуется в [`int`](https://python-all.ru/3.14/library/functions.html#int) и используются все его биты.5253В версии 1 (предназначенной для воспроизведения случайных последовательностей из старых версий Python) алгоритм для [`str`](https://python-all.ru/3.14/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) генерирует более узкий диапазон начальных значений (семян).5455Изменено в версии 3.2: Переход на схему версии 2, которая использует все биты строкового начального значения.5657Изменено в версии 3.11: Параметр *seed* должен быть одного из следующих типов: `None`, [`int`](https://python-all.ru/3.14/library/functions.html#int), [`float`](https://python-all.ru/3.14/library/functions.html#float), [`str`](https://python-all.ru/3.14/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray).5859#### `random.getstate()`6061Возвращает объект, фиксирующий текущее внутреннее состояние генератора. Этот объект можно передать в [`setstate()`](https://python-all.ru/3.14/library/random.html#random.setstate) для восстановления состояния.6263#### `random.setstate(state)`6465*state* должен быть получен из предыдущего вызова [`getstate()`](https://python-all.ru/3.14/library/random.html#random.getstate), а `setstate()` восстанавливает внутреннее состояние генератора в то, которое было на момент вызова `getstate()`.6667## Функции для байтов6869#### `random.randbytes(n)`7071Генерирует *n* случайных байтов.7273Этот метод не следует использовать для генерации токенов безопасности. Вместо этого используйте [`secrets.token_bytes()`](https://python-all.ru/3.14/library/secrets.html#secrets.token_bytes).7475Добавлено в версии 3.9.7677## Функции для целых чисел7879#### `random.randrange(stop)`8081#### `random.randrange(start, stop[, step])`8283Возвращает случайно выбранный элемент из `range(start, stop, step)`.8485Это примерно эквивалентно `choice(range(start, stop, step))`, но поддерживает произвольно большие диапазоны и оптимизировано для распространённых случаев.8687Шаблон позиционных аргументов соответствует функции [`range()`](https://python-all.ru/3.14/library/stdtypes.html#range).8889Именованные аргументы не следует использовать, так как они могут быть интерпретированы неожиданным образом. Например, `randrange(start=100)` интерпретируется как `randrange(0, 100, 1)`.9091Изменено в версии 3.2: `randrange()` стала более совершенной в генерации равномерно распределённых значений. Ранее использовался подход, подобный `int(random()*n)`, который мог давать несколько неравномерные распределения.9293Изменено в версии 3.12: Автоматическое преобразование нецелых типов больше не поддерживается. Вызовы, такие как `randrange(10.0)` и `randrange(Fraction(10, 1))`, теперь вызывают [`TypeError`](https://python-all.ru/3.14/library/exceptions.html#TypeError).9495#### `random.randint(a, b)`9697Возвращает случайное целое *N* такое, что `a <= N <= b`. Псевдоним для `randrange(a, b+1)`.9899#### `random.getrandbits(k)`100101Возвращает неотрицательное целое число Python с *k* случайными битами. Этот метод предоставляется генератором Mersenne Twister, и некоторые другие генераторы также могут реализовывать его как опциональную часть API. Если он доступен, `getrandbits()` позволяет [`randrange()`](https://python-all.ru/3.14/library/random.html#random.randrange) работать с произвольно большими диапазонами.102103Изменено в версии 3.9: Этот метод теперь принимает ноль для *k*.104105## Функции для последовательностей106107#### `random.choice(seq)`108109Возвращает случайный элемент из непустой последовательности *seq*. Если *seq* пуста, возбуждает [`IndexError`](https://python-all.ru/3.14/library/exceptions.html#IndexError).110111#### `random.choices(population, weights=None, *, cum_weights=None, k=1)`112113Возвращает список размера *k* из элементов, выбранных из *population* с возвращением. Если *population* пуста, возбуждает [`IndexError`](https://python-all.ru/3.14/library/exceptions.html#IndexError).114115Если задана последовательность *weights*, выборки производятся в соответствии с относительными весами. Альтернативно, если задана последовательность *cum\_weights*, выборки производятся по накопленным весам (возможно, вычисленным с помощью [`itertools.accumulate()`](https://python-all.ru/3.14/library/itertools.html#itertools.accumulate)). Например, относительные веса `[10, 5, 30, 5]` эквивалентны накопленным весам `[10, 15, 45, 50]`. Внутренне относительные веса преобразуются в накопленные перед выполнением выборок, поэтому передача накопленных весов экономит работу.116117Если не указаны ни *weights*, ни *cum\_weights*, выборки производятся с равной вероятностью. Если передана последовательность весов, её длина должна равняться длине последовательности *population*. Указание и *weights*, и *cum\_weights* приводит к [`TypeError`](https://python-all.ru/3.14/library/exceptions.html#TypeError).118119*weights* или *cum\_weights* могут использовать любой числовой тип, совместимый со значениями [`float`](https://python-all.ru/3.14/library/functions.html#float), возвращаемыми [`random()`](https://python-all.ru/3.14/library/random.html#module-random) (сюда входят целые числа, числа с плавающей запятой и дроби, но не десятичные числа). Предполагается, что веса неотрицательны и конечны. Если все веса равны нулю, возбуждается [`ValueError`](https://python-all.ru/3.14/library/exceptions.html#ValueError).120121Для заданного начального значения функция `choices()` с равными весами обычно выдаёт другую последовательность, чем многократные вызовы [`choice()`](https://python-all.ru/3.14/library/random.html#random.choice). Алгоритм, используемый в `choices()`, применяет арифметику с плавающей запятой для внутренней согласованности и скорости. Алгоритм, используемый в `choice()`, по умолчанию использует целочисленную арифметику с повторными выборками, чтобы избежать малых смещений из-за ошибок округления.122123Добавлено в версии 3.6.124125Изменено в версии 3.9: Возбуждает [`ValueError`](https://python-all.ru/3.14/library/exceptions.html#ValueError), если все веса равны нулю.126127#### `random.shuffle(x)`128129Перемешивает последовательность *x* на месте.130131Чтобы перемешать неизменяемую последовательность и вернуть новый перемешанный список, используйте `sample(x, k=len(x))`.132133Обратите внимание, что даже для небольших `len(x)` общее число перестановок *x* может быстро превысить период большинства генераторов случайных чисел. Это означает, что большинство перестановок длинной последовательности никогда не могут быть сгенерированы. Например, последовательность длины 2080 – это самая длинная, которая умещается в период генератора случайных чисел Mersenne Twister.134135Изменено в версии 3.11: Удалён необязательный параметр *random*.136137#### `random.sample(population, k, *, counts=None)`138139Возвращает список длины *k* из уникальных элементов, выбранных из последовательности population. Используется для случайной выборки без возвращения.140141Возвращает новый список, содержащий элементы из population, не изменяя исходную population. Результирующий список упорядочен по порядку выбора, так что все подсписки также будут корректными случайными выборками. Это позволяет разделить победителей розыгрыша (выборку) на обладателей главного и второго призов (подсписки).142143Элементы population не обязаны быть [хэшируемыми](https://python-all.ru/3.14/glossary.html#term-hashable) или уникальными. Если population содержит повторения, то каждое вхождение является возможным элементом выборки.144145Повторяющиеся элементы можно указывать по одному или с помощью необязательного параметра *counts*, передаваемого только по ключу. Например, `sample(['red', 'blue'], counts=[4, 2], k=5)` эквивалентно `sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)`.146147Чтобы выбрать выборку из диапазона целых чисел, используйте объект [`range()`](https://python-all.ru/3.14/library/stdtypes.html#range) в качестве аргумента. Это особенно быстро и эффективно по памяти при выборке из большой популяции: `sample(range(10000000), k=60)`.148149Если размер выборки превышает размер популяции, возбуждается исключение [`ValueError`](https://python-all.ru/3.14/library/exceptions.html#ValueError).150151Изменено в версии 3.9: Добавлен параметр *counts*.152153Изменено в версии 3.11: Параметр *population* должен быть последовательностью. Автоматическое преобразование множеств в списки больше не поддерживается.154155## Дискретные распределения156157Следующая функция генерирует дискретное распределение.158159#### `random.binomialvariate(n=1, p=0.5)`160161[Биномиальное распределение](https://python-all.ru/3.14/library/random.html). Возвращает количество успехов для *n* независимых испытаний, где вероятность успеха в каждом испытании равна *p*:162163Математически эквивалентно:164165```python166sum(random() < p for i in range(n))167```168169Количество испытаний *n* должно быть неотрицательным целым числом. Вероятность успеха *p* должна быть в диапазоне `0.0 <= p <= 1.0`. Результат – целое число в диапазоне `0 <= X <= n`.170171Добавлено в версии 3.12.172173## Вещественные распределения174175Следующие функции генерируют конкретные вещественные распределения. Имена параметров функций соответствуют переменным в уравнении распределения, как принято в математической практике; большинство этих уравнений можно найти в любом учебнике по статистике.176177#### `random.random()`178179Возвращает следующее случайное число с плавающей запятой в диапазоне `0.0 <= X < 1.0`180181#### `random.uniform(a, b)`182183Возвращает случайное число с плавающей запятой *N* такое, что `a <= N <= b` при `a <= b` и `b <= N <= a` при `b < a`.184185Значение конечной точки `b` может как входить, так и не входить в диапазон в зависимости от округления чисел с плавающей запятой в выражении `a + (b-a) * random()`.186187#### `random.triangular(low, high, mode)`188189Возвращает случайное число с плавающей запятой *N* такое, что `low <= N <= high` и с указанной *модой* между этими границами. Границы *low* и *high* по умолчанию равны нулю и единице. Аргумент *mode* по умолчанию равен середине между границами, что даёт симметричное распределение.190191#### `random.betavariate(alpha, beta)`192193Бета-распределение. Условия на параметры: `alpha > 0` и `beta > 0`. Возвращаемые значения находятся в диапазоне от 0 до 1.194195#### `random.expovariate(lambd=1.0)`196197Экспоненциальное распределение. *lambd* – это 1.0, делённая на желаемое среднее. Оно должно быть ненулевым. (Параметр мог бы называться «lambda», но это зарезервированное слово в Python.) Возвращаемые значения находятся в диапазоне от 0 до положительной бесконечности, если *lambd* положительно, и от отрицательной бесконечности до 0, если *lambd* отрицательно.198199Изменено в версии 3.12: Добавлено значение по умолчанию для `lambd`.200201#### `random.gammavariate(alpha, beta)`202203Гамма-распределение. (*Не* гамма-функция!) Параметры формы и масштаба, *alpha* и *beta*, должны иметь положительные значения. (Соглашения о вызовах различаются, и некоторые источники определяют 'beta' как обратную величину масштаба.)204205Функция плотности распределения вероятности:206207```python208          x ** (alpha - 1) * math.exp(-x / beta)209pdf(x) =  --------------------------------------210            math.gamma(alpha) * beta ** alpha211```212213#### `random.gauss(mu=0.0, sigma=1.0)`214215Нормальное распределение, также называемое распределением Гаусса. *mu* – это среднее, а *sigma* – это стандартное отклонение. Эта функция немного быстрее, чем функция [`normalvariate()`](https://python-all.ru/3.14/library/random.html#random.normalvariate), определённая ниже.216217Примечание о многопоточности: когда два потока одновременно вызывают эту функцию, они могут получить одно и то же возвращаемое значение. Этого можно избежать тремя способами: 1) Пусть каждый поток использует свой экземпляр генератора случайных чисел. 2) Установите блокировки вокруг всех вызовов. 3) Используйте более медленную, но потокобезопасную функцию [`normalvariate()`](https://python-all.ru/3.14/library/random.html#random.normalvariate).218219Изменено в версии 3.11: *mu* и *sigma* теперь имеют аргументы по умолчанию.220221#### `random.lognormvariate(mu, sigma)`222223Логнормальное распределение. Если взять натуральный логарифм этого распределения, получится нормальное распределение со средним *mu* и стандартным отклонением *sigma*. *mu* может принимать любое значение, а *sigma* должна быть больше нуля.224225#### `random.normalvariate(mu=0.0, sigma=1.0)`226227Нормальное распределение. *mu* – это среднее, а *sigma* – стандартное отклонение.228229Изменено в версии 3.11: *mu* и *sigma* теперь имеют аргументы по умолчанию.230231#### `random.vonmisesvariate(mu, kappa)`232233*mu* – это средний угол, выраженный в радианах от 0 до 2\**pi*, а *kappa* – параметр концентрации, который должен быть больше или равен нулю. Если *kappa* равен нулю, это распределение сводится к равномерному случайному углу в диапазоне от 0 до 2\**pi*.234235#### `random.paretovariate(alpha)`236237Распределение Парето. *alpha* – параметр формы.238239#### `random.weibullvariate(alpha, beta)`240241Распределение Вейбулла. *alpha* – параметр масштаба, а *beta* – параметр формы.242243## Альтернативный генератор244245#### `class random.Random([seed])`246247Класс, реализующий генератор псевдослучайных чисел по умолчанию, используемый модулем `random`.248249Изменено в версии 3.11: Ранее *seed* мог быть любым хешируемым объектом. Теперь он ограничен: `None`, [`int`](https://python-all.ru/3.14/library/functions.html#int), [`float`](https://python-all.ru/3.14/library/functions.html#float), [`str`](https://python-all.ru/3.14/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.14/library/stdtypes.html#bytearray).250251Подклассы `Random` должны переопределить следующие методы, если они хотят использовать другой базовый генератор:252253#### `seed(a=None, version=2)`254255Переопределите этот метод в подклассах, чтобы настроить `seed()` поведение экземпляров `Random`.256257#### `getstate()`258259Переопределите этот метод в подклассах, чтобы настроить `getstate()` поведение экземпляров `Random`.260261#### `setstate(state)`262263Переопределите этот метод в подклассах, чтобы настроить `setstate()` поведение экземпляров `Random`.264265#### `random()`266267Переопределите этот метод в подклассах, чтобы настроить `random()` поведение экземпляров `Random`.268269При желании подкласс пользовательского генератора может также предоставить следующий метод:270271#### `getrandbits(k)`272273Переопределите этот метод в подклассах, чтобы настроить `getrandbits()` поведение экземпляров `Random`.274275#### `randbytes(n)`276277Переопределите этот метод в подклассах, чтобы настроить `randbytes()` поведение экземпляров `Random`.278279#### `class random.SystemRandom([seed])`280281Класс, использующий функцию [`os.urandom()`](https://python-all.ru/3.14/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой. Доступен не на всех системах. Не зависит от состояния программного обеспечения, и последовательности невоспроизводимы. Соответственно, метод [`seed()`](https://python-all.ru/3.14/library/random.html#random.seed) не действует и игнорируется. Методы [`getstate()`](https://python-all.ru/3.14/library/random.html#random.getstate) и [`setstate()`](https://python-all.ru/3.14/library/random.html#random.setstate) вызывают [`NotImplementedError`](https://python-all.ru/3.14/library/exceptions.html#NotImplementedError) при вызове.282283## Примечания о воспроизводимости284285Иногда бывает полезно воспроизводить последовательности, выдаваемые генератором псевдослучайных чисел. При повторном использовании одного и того же начального значения (seed) одна и та же последовательность должна воспроизводиться от запуска к запуску, если не запущено несколько потоков.286287Большинство алгоритмов и функций инициализации генератора модуля random могут меняться в разных версиях Python, но два аспекта гарантированно остаются неизменными:288289- Если будет добавлен новый метод инициализации, будет предложен обратно совместимый инициализатор.290- Метод [`random()`](https://python-all.ru/3.14/library/random.html#random.Random.random) генератора продолжит выдавать ту же последовательность, если совместимому инициализатору передать то же начальное значение.291292## Примеры293294Простые примеры:295296```python297>>> random()                          # Случайное число с плавающей точкой: 0.0 <= x < 1.02980.37444887175646646299300>>> uniform(2.5, 10.0)                # Случайное число с плавающей точкой: 2.5 <= x <= 10.03013.1800146073117523302303>>> expovariate(1 / 5)                # Интервал между поступлениями в среднем 5 секунд3045.148957571865031305306>>> randrange(10)                     # Целое число от 0 до 9 включительно3077308309>>> randrange(0, 101, 2)              # Чётное целое число от 0 до 100 включительно31026311312>>> choice(['win', 'lose', 'draw'])   # Один случайный элемент из последовательности313'draw'314315>>> deck = 'ace two three four'.split()316>>> shuffle(deck)                     # Перемешать список317>>> deck318['four', 'two', 'ace', 'three']319320>>> sample([10, 20, 30, 40, 50], k=4) # Четыре выборки без возвращения321[40, 10, 50, 30]322```323324Симуляции:325326```python327>>> # Шесть вращений колеса рулетки (взвешенная выборка с возвращением)328>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)329['red', 'green', 'black', 'black', 'red', 'black']330331>>> # Раздать 20 карт без возвращения из колоды332>>> # из 52 игральных карт и определить долю карт333>>> # со значением десять: десятка, валет, дама или король.334>>> deal = sample(['tens', 'low cards'], counts=[16, 36], k=20)335>>> deal.count('tens') / 203360.15337338>>> # Оценить вероятность выпадения 5 или более орлов за 7 подбрасываний339>>> # несимметричной монеты, которая выпадает орлом в 60% случаев.340>>> sum(binomialvariate(n=7, p=0.6) >= 5 for i in range(10_000)) / 10_0003410.4169342343>>> # Вероятность того, что медиана 5 выборок окажется в двух средних квартилях344>>> def trial():345...     return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500346...347>>> sum(trial() for i in range(10_000)) / 10_0003480.7958349```350351Пример [статистического бутстрепа](https://python-all.ru/3.14/library/random.html) с использованием повторной выборки с возвращением для оценки доверительного интервала для среднего значения выборки:352353```python354# https://www.thoughtco.com/example-of-bootstrapping-3126155355from statistics import fmean as mean356from random import choices357358data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]359means = sorted(mean(choices(data, k=len(data))) for i in range(100))360print(f'The sample mean of {mean(data):.1f} has a 90% confidence '361      f'interval from {means[5]:.1f} to {means[94]:.1f}')362```363364Пример [пермутационного теста с повторной выборкой](https://python-all.ru/3.14/library/random.html) для определения статистической значимости или [p-значения](https://python-all.ru/3.14/library/random.html) наблюдаемого различия между эффектами препарата и плацебо:365366```python367# Пример из книги "Statistics is Easy" Денниса Шаши и Манды Уилсон368from statistics import fmean as mean369from random import shuffle370371drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]372placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]373observed_diff = mean(drug) - mean(placebo)374375n = 10_000376count = 0377combined = drug + placebo378for i in range(n):379    shuffle(combined)380    new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])381    count += (new_diff >= observed_diff)382383print(f'{n} label reshufflings produced only {count} instances with a difference')384print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')385print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')386print(f'hypothesis that there is no difference between the drug and the placebo.')387```388389Моделирование времени поступления и обслуживания запросов для многоканальной очереди:390391```python392from heapq import heapify, heapreplace393from random import expovariate, gauss394from statistics import mean, quantiles395396average_arrival_interval = 5.6397average_service_time = 15.0398stdev_service_time = 3.5399num_servers = 3400401waits = []402arrival_time = 0.0403servers = [0.0] * num_servers  # время, когда каждый сервер становится доступным404heapify(servers)405for i in range(1_000_000):406    arrival_time += expovariate(1.0 / average_arrival_interval)407    next_server_available = servers[0]408    wait = max(0.0, next_server_available - arrival_time)409    waits.append(wait)410    service_duration = max(0.0, gauss(average_service_time, stdev_service_time))411    service_completed = arrival_time + wait + service_duration412    heapreplace(servers, service_completed)413414print(f'Mean wait: {mean(waits):.1f}   Max wait: {max(waits):.1f}')415print('Quartiles:', [round(q, 1) for q in quantiles(waits)])416```417418> **См. также**419>420> [Statistics for Hackers](https://python-all.ru/3.14/library/random.html) – видеоурок от [Jake Vanderplas](https://python-all.ru/3.14/library/random.html) по статистическому анализу, использующему всего несколько фундаментальных понятий, включая моделирование, выборку, перемешивание и кросс-валидацию.421>422> [Economics Simulation](https://python-all.ru/3.14/library/random.html) – симуляция рынка от [Peter Norvig](https://python-all.ru/3.14/library/random.html), демонстрирующая эффективное использование многих инструментов и распределений, предоставляемых этим модулем (gauss, uniform, sample, betavariate, choice, triangular и randrange).423>424> [A Concrete Introduction to Probability (using Python)](https://python-all.ru/3.14/library/random.html) – учебное пособие от [Peter Norvig](https://python-all.ru/3.14/library/random.html), охватывающее основы теории вероятностей, написание симуляций и выполнение анализа данных с помощью Python.425426## Рецепты427428Эти рецепты показывают, как эффективно делать случайный выбор из комбинаторных итераторов модуля [`itertools`](https://python-all.ru/3.14/library/itertools.html#module-itertools):429430```python431import random432433def random_product(*iterables, repeat=1):434    "Random selection from itertools.product(*iterables, repeat=repeat)"435    pools = tuple(map(tuple, iterables)) * repeat436    return tuple(map(random.choice, pools))437438def random_permutation(iterable, r=None):439    "Random selection from itertools.permutations(iterable, r)"440    pool = tuple(iterable)441    r = len(pool) if r is None else r442    return tuple(random.sample(pool, r))443444def random_combination(iterable, r):445    "Random selection from itertools.combinations(iterable, r)"446    pool = tuple(iterable)447    n = len(pool)448    indices = sorted(random.sample(range(n), r))449    return tuple(pool[i] for i in indices)450451def random_combination_with_replacement(iterable, r):452    "Choose r elements with replacement.  Order the result to match the iterable."453    # Результат будет в set(itertools.combinations_with_replacement(iterable, r)).454    pool = tuple(iterable)455    n = len(pool)456    indices = sorted(random.choices(range(n), k=r))457    return tuple(pool[i] for i in indices)458459def random_derangement(iterable):460    "Choose a permutation where no element stays in its original position."461    seq = tuple(iterable)462    if len(seq) < 2:463        if not seq:464            return ()465        raise IndexError('No derangments to choose from')466    perm = list(range(len(seq)))467    start = tuple(perm)468    while True:469        random.shuffle(perm)470        if all(p != q for p, q in zip(start, perm)):471            return tuple([seq[i] for i in perm])472```473474По умолчанию [`random()`](https://python-all.ru/3.14/library/random.html#random.random) возвращает числа, кратные 2⁻⁵³, в диапазоне *0.0 ≤ x \< 1.0*. Все такие числа равномерно распределены и точно представимы как числа с плавающей запятой Python. Однако многие другие представимые числа с плавающей запятой в этом интервале не могут быть выбраны. Например, `0.05954861408025609` не является целым кратным 2⁻⁵³.475476Следующий рецепт использует другой подход. Все числа с плавающей запятой в интервале могут быть выбраны. Мантисса берётся из равномерного распределения целых чисел в диапазоне *2⁵² ≤ mantissa \< 2⁵³*. Показатель степени берётся из геометрического распределения, где показатели меньше *-53* встречаются вдвое реже, чем следующий больший показатель.477478```python479from random import Random480from math import ldexp481482class FullRandom(Random):483484    def random(self):485        mantissa = 0x10_0000_0000_0000 | self.getrandbits(52)486        exponent = -53487        x = 0488        while not x:489            x = self.getrandbits(32)490            exponent += x.bit_length() - 32491        return ldexp(mantissa, exponent)492```493494Все [вещественнозначные распределения](https://python-all.ru/3.14/library/random.html#real-valued-distributions) в классе будут использовать новый метод:495496```python497>>> fr = FullRandom()498>>> fr.random()4990.05954861408025609500>>> fr.expovariate(0.25)5018.87925541791544502```503504Этот рецепт концептуально эквивалентен алгоритму, который выбирает из всех чисел, кратных 2⁻¹⁰⁷⁴, в диапазоне *0.0 ≤ x \< 1.0*. Все такие числа равномерно распределены, но большинство приходится округлять вниз до ближайшего представимого числа с плавающей запятой Python. (Значение 2⁻¹⁰⁷⁴ – это наименьшее положительное ненормализованное число с плавающей запятой, равное `math.ulp(0.0)`.)505506> **См. также**507>508> [Generating Pseudo-random Floating-Point Values](https://python-all.ru/3.14/library/random.html) – статья Аллена Б. Дауни, описывающая способы генерации более мелкозернистых чисел с плавающей запятой, чем обычно генерирует [`random()`](https://python-all.ru/3.14/library/random.html#random.random).509510## Использование командной строки511512Добавлено в версии 3.13.513514Модуль `random` можно запускать из командной строки.515516```sh517python -m random [-h] [-c CHOICE [CHOICE ...] | -i N | -f N] [input ...]518```519520Принимаются следующие опции:521522#### `-h, --help`523524Показать справку и выйти.525526#### `-c CHOICE [CHOICE ...]`527528#### `--choice CHOICE [CHOICE ...]`529530Выводит случайный элемент, используя [`choice()`](https://python-all.ru/3.14/library/random.html#random.choice).531532#### `-i <N>`533534#### `--integer <N>`535536Выводит случайное целое число от 1 до N включительно, используя [`randint()`](https://python-all.ru/3.14/library/random.html#random.randint).537538#### `-f <N>`539540#### `--float <N>`541542Выводит случайное число с плавающей запятой от 0 до N включительно, используя [`uniform()`](https://python-all.ru/3.14/library/random.html#random.uniform).543544Если параметры не указаны, вывод зависит от ввода:545546- Строка или несколько аргументов: то же, что [`--choice`](https://python-all.ru/3.14/library/random.html#cmdoption-random-choice).547- Целое число: то же, что [`--integer`](https://python-all.ru/3.14/library/random.html#cmdoption-random-integer).548- Float: то же, что и [`--float`](https://python-all.ru/3.14/library/random.html#cmdoption-random-float).549550## Пример командной строки551552Вот несколько примеров интерфейса командной строки `random`:553554```console555$ # Выбрать один случайным образом556$ python -m random egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"557Lobster Thermidor aux crevettes with a Mornay sauce558559$ # Случайное целое число560$ python -m random 65616562563$ # Случайное число с плавающей запятой564$ python -m random 1.85651.7080016272295635566567$ # С явными аргументами568$ python  -m random --choice egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"569egg570571$ python -m random --integer 65723573574$ python -m random --float 1.85751.5666339105010318576577$ python -m random --integer 65785579580$ python -m random --float 65813.1942323316565915582```583