random.md
1> **Источник:** https://python-all.ru/3.4/library/random.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 9.6. [`random`](https://python-all.ru/3.4/library/random.html#module-random) – Генерация псевдослучайных чисел89**Исходный код:** [Lib/random.py](https://python-all.ru/src/3.4/Lib/random.py)1011---1213Этот модуль реализует генераторы псевдослучайных чисел для различных распределений.1415Для целых чисел есть равномерный выбор из диапазона. Для последовательностей есть равномерный выбор случайного элемента, функция для генерации случайной перестановки списка на месте и функция для случайной выборки без возвращения.1617На вещественной прямой есть функции для вычисления равномерного, нормального (гауссовского), логнормального, отрицательного экспоненциального, гамма и бета распределений. Для генерации распределений углов доступно распределение фон Мизеса.1819Почти все функции модуля зависят от базовой функции [`random()`](https://python-all.ru/3.4/library/random.html#module-random), которая генерирует случайное число с плавающей запятой, равномерно распределённое в полуоткрытом интервале \[0.0, 1.0). В Python в качестве основного генератора используется вихрь Мерсенна. Он генерирует числа с плавающей запятой точностью 53 бита и имеет период 2\*\*19937-1. Базовая реализация на C быстра и потокобезопасна. Вихрь Мерсенна – один из наиболее тщательно протестированных генераторов случайных чисел. Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографии.2021Функции, предоставляемые этим модулем, на самом деле являются привязанными методами скрытого экземпляра класса `random.Random`. Можно создать собственные экземпляры `Random`, чтобы получить генераторы, которые не разделяют состояние.2223Класс `Random` также можно наследовать, если требуется использовать другой базовый генератор собственной разработки: в этом случае переопределите методы [`random()`](https://python-all.ru/3.4/library/random.html#module-random), [`seed()`](https://python-all.ru/3.4/library/random.html#random.seed), [`getstate()`](https://python-all.ru/3.4/library/random.html#random.getstate) и [`setstate()`](https://python-all.ru/3.4/library/random.html#random.setstate). При необходимости новый генератор может предоставить метод [`getrandbits()`](https://python-all.ru/3.4/library/random.html#random.getrandbits) – это позволяет [`randrange()`](https://python-all.ru/3.4/library/random.html#random.randrange) выполнять выборки из произвольно больших диапазонов.2425Модуль [`random`](https://python-all.ru/3.4/library/random.html#module-random) также предоставляет класс [`SystemRandom`](https://python-all.ru/3.4/library/random.html#random.SystemRandom), который использует системную функцию [`os.urandom()`](https://python-all.ru/3.4/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой.2627> **Предупреждение**28>29> Псевдослучайные генераторы этого модуля не следует использовать в целях безопасности. Используйте [`os.urandom()`](https://python-all.ru/3.4/library/os.html#os.urandom) или [`SystemRandom`](https://python-all.ru/3.4/library/random.html#random.SystemRandom), если требуется криптографически стойкий генератор псевдослучайных чисел.3031Функции учёта:3233#### `random.seed(a=None, version=2)`3435Инициализирует генератор случайных чисел.3637Если *a* опущен или равен `None`, используется текущее системное время. Если операционная система предоставляет источники случайности, они используются вместо системного времени (см. функцию [`os.urandom()`](https://python-all.ru/3.4/library/os.html#os.urandom) для подробностей о доступности).3839Если *a* – целое число, оно используется напрямую.4041В версии 2 (по умолчанию) объект [`str`](https://python-all.ru/3.4/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) или [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray) преобразуется в [`int`](https://python-all.ru/3.4/library/functions.html#int), и используются все его биты. В версии 1 вместо этого используется [`hash()`](https://python-all.ru/3.4/library/functions.html#hash) от *a*.4243Изменено в версии 3.2: Переход на схему версии 2, которая использует все биты строкового начального значения.4445#### `random.getstate()`4647Возвращает объект, фиксирующий текущее внутреннее состояние генератора. Этот объект можно передать в [`setstate()`](https://python-all.ru/3.4/library/random.html#random.setstate) для восстановления состояния.4849#### `random.setstate(state)`5051*state* должен быть получен из предыдущего вызова [`getstate()`](https://python-all.ru/3.4/library/random.html#random.getstate), и [`setstate()`](https://python-all.ru/3.4/library/random.html#random.setstate) восстанавливает внутреннее состояние генератора в то, каким оно было на момент вызова [`getstate()`](https://python-all.ru/3.4/library/random.html#random.getstate).5253#### `random.getrandbits(k)`5455Возвращает целое число Python с *k* случайными битами. Этот метод предоставляется генератором MersenneTwister, и некоторые другие генераторы также могут предоставлять его как опциональную часть API. При наличии [`getrandbits()`](https://python-all.ru/3.4/library/random.html#random.getrandbits) позволяет [`randrange()`](https://python-all.ru/3.4/library/random.html#random.randrange) работать с произвольно большими диапазонами.5657Функции для целых чисел:5859#### `random.randrange(stop)`6061#### `random.randrange(start, stop[, step])`6263Возвращает случайно выбранный элемент из `range(start, stop, step)`. Это эквивалентно `choice(range(start, stop, step))`, но не создаёт объект range.6465Шаблон позиционных аргументов совпадает с шаблоном [`range()`](https://python-all.ru/3.4/library/stdtypes.html#range). Именованные аргументы использовать не следует, так как функция может использовать их неожиданным образом.6667Изменено в версии 3.2: [`randrange()`](https://python-all.ru/3.4/library/random.html#random.randrange) теперь более тщательно генерирует равномерно распределённые значения. Ранее использовался подход вроде `int(random()*n)`, который мог приводить к незначительным неравномерностям распределения.6869#### `random.randint(a, b)`7071Возвращает случайное целое число *N*, такое что `a <= N <= b`. Псевдоним для `randrange(a, b+1)`.7273Функции для последовательностей:7475#### `random.choice(seq)`7677Возвращает случайный элемент из непустой последовательности *seq*. Если *seq* пуста, возбуждает [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError).7879#### `random.shuffle(x[, random])`8081Перемешивает последовательность *x* на месте. Необязательный аргумент *random* – функция без аргументов, возвращающая случайное число с плавающей запятой в \[0.0, 1.0); по умолчанию это функция [`random()`](https://python-all.ru/3.4/library/random.html#module-random).8283Обратите внимание, что даже для довольно малого `len(x)` общее число перестановок *x* больше периода большинства генераторов случайных чисел; это означает, что большинство перестановок длинной последовательности никогда не могут быть сгенерированы.8485#### `random.sample(population, k)`8687Возвращает список длины *k* из уникальных элементов, выбранных из последовательности population или множества. Используется для случайной выборки без возвращения.8889Возвращает новый список, содержащий элементы из population, не изменяя исходную population. Результирующий список упорядочен по порядку выбора, так что все подсписки также будут корректными случайными выборками. Это позволяет разделить победителей розыгрыша (выборку) на обладателей главного и второго призов (подсписки).9091Элементы population не обязаны быть [*хэшируемыми*](https://python-all.ru/3.4/glossary.html#term-hashable) или уникальными. Если population содержит повторения, то каждое вхождение является возможным элементом выборки.9293Чтобы выбрать выборку из диапазона целых чисел, используйте объект [`range()`](https://python-all.ru/3.4/library/stdtypes.html#range) в качестве аргумента. Это особенно быстро и эффективно по памяти для выборки из большой популяции: `sample(range(10000000), 60)`.9495Если размер выборки больше размера популяции, возбуждается [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError).9697Следующие функции генерируют конкретные вещественные распределения. Имена параметров функций соответствуют переменным в уравнении распределения, как принято в математической практике; большинство этих уравнений можно найти в любом учебнике по статистике.9899#### `random.random()`100101Возвращает следующее случайное число с плавающей запятой в диапазоне \[0.0, 1.0).102103#### `random.uniform(a, b)`104105Возвращает случайное число с плавающей запятой *N* такое, что `a <= N <= b` для `a <= b` и `b <= N <= a` для `b < a`.106107Конечное значение `b` может входить или не входить в диапазон в зависимости от округления чисел с плавающей запятой в уравнении `a + (b-a) * random()`.108109#### `random.triangular(low, high, mode)`110111Возвращает случайное число с плавающей запятой *N* такое, что `low <= N <= high` и с заданной *mode* между этими границами. Границы *low* и *high* по умолчанию равны нулю и единице. Аргумент *mode* по умолчанию равен середине между границами, что даёт симметричное распределение.112113#### `random.betavariate(alpha, beta)`114115Бета-распределение. Условия на параметры: `alpha > 0` и `beta > 0`. Возвращаемые значения находятся в диапазоне от 0 до 1.116117#### `random.expovariate(lambd)`118119Экспоненциальное распределение. *lambd* – это 1.0, делённая на желаемое среднее. Оно должно быть ненулевым. (Параметр мог бы называться «lambda», но это зарезервированное слово в Python.) Возвращаемые значения находятся в диапазоне от 0 до положительной бесконечности, если *lambd* положительно, и от отрицательной бесконечности до 0, если *lambd* отрицательно.120121#### `random.gammavariate(alpha, beta)`122123Гамма-распределение. (*Не* гамма-функция!) Условия на параметры: `alpha > 0` и `beta > 0`.124125Функция плотности распределения вероятности:126127```python128 x ** (alpha - 1) * math.exp(-x / beta)129pdf(x) = --------------------------------------130 math.gamma(alpha) * beta ** alpha131```132133#### `random.gauss(mu, sigma)`134135Гауссово распределение. *mu* – это среднее, а *sigma* – это стандартное отклонение. Эта функция немного быстрее, чем [`normalvariate()`](https://python-all.ru/3.4/library/random.html#random.normalvariate), определённая ниже.136137#### `random.lognormvariate(mu, sigma)`138139Логнормальное распределение. Если взять натуральный логарифм этого распределения, получится нормальное распределение со средним *mu* и стандартным отклонением *sigma*. *mu* может принимать любое значение, а *sigma* должна быть больше нуля.140141#### `random.normalvariate(mu, sigma)`142143Нормальное распределение. *mu* – это среднее, а *sigma* – стандартное отклонение.144145#### `random.vonmisesvariate(mu, kappa)`146147*mu* – это средний угол, выраженный в радианах от 0 до 2\**pi*, а *kappa* – параметр концентрации, который должен быть больше или равен нулю. Если *kappa* равен нулю, это распределение сводится к равномерному случайному углу в диапазоне от 0 до 2\**pi*.148149#### `random.paretovariate(alpha)`150151Распределение Парето. *alpha* – параметр формы.152153#### `random.weibullvariate(alpha, beta)`154155Распределение Вейбулла. *alpha* – параметр масштаба, а *beta* – параметр формы.156157Альтернативный генератор:158159#### `class random.SystemRandom([seed])`160161Класс, использующий функцию [`os.urandom()`](https://python-all.ru/3.4/library/os.html#os.urandom) для генерации случайных чисел из источников, предоставляемых операционной системой. Доступен не на всех системах. Не полагается на состояние программного обеспечения, и последовательности невоспроизводимы. Соответственно, метод [`seed()`](https://python-all.ru/3.4/library/random.html#random.seed) не действует и игнорируется. Методы [`getstate()`](https://python-all.ru/3.4/library/random.html#random.getstate) и [`setstate()`](https://python-all.ru/3.4/library/random.html#random.setstate) вызывают [`NotImplementedError`](https://python-all.ru/3.4/library/exceptions.html#NotImplementedError) при вызове.162163> **См. также**164>165> M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator”, ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998.166>167> [Complementary-Multiply-with-Carry recipe](https://python-all.ru/3.4/library/random.html) для совместимого альтернативного генератора случайных чисел с длинным периодом и сравнительно простыми операциями обновления.168169## 9.6.1. Замечания о воспроизводимости170171Иногда бывает полезно воспроизводить последовательности, выдаваемые генератором псевдослучайных чисел. При повторном использовании одного и того же начального значения (seed) одна и та же последовательность должна воспроизводиться от запуска к запуску, если не запущено несколько потоков.172173Большинство алгоритмов и функций инициализации генератора модуля random могут меняться в разных версиях Python, но два аспекта гарантированно остаются неизменными:174175- Если будет добавлен новый метод инициализации, будет предложен обратно совместимый инициализатор.176- Метод [`random()`](https://python-all.ru/3.4/library/random.html#module-random) генератора будет продолжать выдавать ту же последовательность, если совместимому инициализатору передано то же начальное значение.177178## 9.6.2. Примеры и рецепты179180Базовое использование:181182```python183>>> random.random() # Случайный float x, 0.0 <= x < 1.01840.37444887175646646185186>>> random.uniform(1, 10) # Случайный float x, 1.0 <= x < 10.01871.1800146073117523188189>>> random.randrange(10) # Целое число от 0 до 91907191192>>> random.randrange(0, 101, 2) # Чётное целое число от 0 до 10019326194195>>> random.choice('abcdefghij') # Один случайный элемент196'c'197198>>> items = [1, 2, 3, 4, 5, 6, 7]199>>> random.shuffle(items)200>>> items201[7, 3, 2, 5, 6, 4, 1]202203>>> random.sample([1, 2, 3, 4, 5], 3) # Три элемента без повторений204[4, 1, 5]205```206207Частая задача – выполнить [`random.choice()`](https://python-all.ru/3.4/library/random.html#random.choice) с взвешенными вероятностями.208209Если веса представляют собой небольшие целые отношения, простой метод – построить выборку с повторениями:210211```python212>>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)]213>>> population = [val for val, cnt in weighted_choices for i in range(cnt)]214>>> random.choice(population)215'Green'216```217218Более общий подход – расположить веса в виде кумулятивного распределения с помощью [`itertools.accumulate()`](https://python-all.ru/3.4/library/itertools.html#itertools.accumulate), а затем найти случайное значение с помощью [`bisect.bisect()`](https://python-all.ru/3.4/library/bisect.html#bisect.bisect):219220```python221>>> choices, weights = zip(*weighted_choices)222>>> cumdist = list(itertools.accumulate(weights))223>>> x = random.random() * cumdist[-1]224>>> choices[bisect.bisect(cumdist, x)]225'Blue'226```227