Генерация случайных чисел с помощью Python random

Раздел: Стандартная библиотека Python -> Random

Основы генерации случайных чисел в Python

Модуль random в Python предоставляет удобные функции для генерации псевдослучайных чисел. Наиболее эффективное решение для типовых задач - комбинация функций random.random(), random.randint(), random.choice() и random.shuffle(). Они покрывают 90% потребностей: случайные числа с плавающей точкой, целые числа, выбор элемента из последовательности, перемешивание списка.

Пример базового использования:

import random

# случайное число от 0 до 1
print(random.random())
# случайное целое от 1 до 10
print(random.randint(1, 10))
# случайный элемент из списка
items = ['камень', 'ножницы', 'бумага']
print(random.choice(items))
# перемешивание списка
cards = ['туз', 'король', 'дама']
random.shuffle(cards)
print(cards)

массив случайных чисел python (генерация массива случайных чисел в python)

0.374540
7
ножницы
['король', 'дама', 'туз']

Python случайный элемент массива (выбор случайного элемента из массива)

Эти функции основаны на алгоритме Mersenne Twister, который обеспечивает высокую производительность и хорошее качество случайности для большинства приложений.

Как получить случайное целое число в диапазоне?

Функция randint(a, b) возвращает целое N такое, что a ≤ N ≤ b. Для интервала с шагом используется randrange(start, stop[, step]).

import random
# кубик от 1 до 6
dice = random.randint(1, 6)
print(dice)
# чётное число от 0 до 10
even = random.randrange(0, 11, 2)
print(even)

Python random (генерация случайных чисел)

4
6

Типичная ошибка: путаница с границами: randint включает обе границы, randrange исключает правую границу. Проблема: если нужно получить число от 0 до 9, вызов randint(0, 9) корректен, а randrange(0, 10) тоже корректен, но некоторые путают stop. Также не стоит использовать random.seed() без необходимости, так как это делает последовательность предсказуемой.

Как получить случайное число с плавающей точкой?

random() даёт число в [0.0, 1.0). Для произвольного интервала используйте uniform(a, b), который возвращает float в диапазоне [a, b] или [b, a] в зависимости от порядка.

import random
# случайная температура от -10 до 40
temp = random.uniform(-10.0, 40.0)
print(f"{temp:.2f}")
# гауссово распределение
mu, sigma = 100, 15
iq = random.gauss(mu, sigma)
print(f"{iq:.1f}")
15.73
112.4

Частая проблема: при использовании uniform с большим количеством чисел производительность может быть ниже, чем прямое преобразование random() в нужный диапазон. Решение: a + (b - a) * random.random().

Как сделать случайную выборку из списка?

random.choice(seq) выбирает один элемент. random.sample(population, k) возвращает k уникальных элементов без повторений. random.choices(population, weights=None, k=1) позволяет выбирать с повторениями и весами.

import random
names = ['Алиса', 'Боб', 'Чарли', 'Диана']
# один случайный
print(random.choice(names))
# два уникальных
print(random.sample(names, 2))
# три с повторениями, с весами
print(random.choices(names, weights=[1,2,3,4], k=3))
Боб
['Чарли', 'Алиса']
['Диана', 'Диана', 'Чарли']

Ошибка: при выборке sample с k больше длины списка возникает исключение ValueError. Решение: проверять размер или использовать choices с повторениями. Также веса в choices не обязательно суммируются в единицу, они нормируются автоматически.

Как перемешать список?

random.shuffle(lst) перемешивает список на месте (изменяет сам список). Для нового перемешанного списка без изменения оригинала используйте random.sample(lst, len(lst)).

import random
deck = list(range(1, 53))
# на месте
random.shuffle(deck)
print(deck[:5])
# новый список
new_deck = random.sample(deck, len(deck))
print(new_deck[:5])
[34, 12, 7, 49, 21]
[3, 45, 30, 18, 52]

Проблема: shuffle не работает с неизменяемыми типами (кортежи, строки). Решение: преобразовать в список, перемешать, затем вернуть обратно. Также не стоит забывать, что shuffle использует тот же генератор, что и другие функции; если установить seed до перемешивания, результат будет предсказуем.

Как повторить случайную последовательность?

Для отладки или тестов часто нужно получить одинаковую последовательность при каждом запуске. Для этого используется random.seed(a=None, version=2). Если передать одинаковое seed, генератор будет выдавать те же числа.

import random
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])
[82, 15, 4, 95, 36]
[82, 15, 4, 95, 36]

Ошибка: установка seed внутри цикла или при многопоточности (генератор не потокобезопасен) может привести к непредсказуемым результатам. Рекомендуется создавать отдельные экземпляры Random: rng = random.Random(seed).

Как получить криптостойкие случайные числа?

Модуль random не подходит для криптографии, так как его алгоритм предсказуем при известном состоянии. Используйте модуль secrets, который основан на системных энтропийных источниках.

import secrets
# безопасный выбор пароля
symbols = 'abcdefghijklmnopqrstuvwxyz0123456789'
pwd = ''.join(secrets.choice(symbols) for _ in range(8))
print(pwd)
# безопасное целое число от 0 до 255
print(secrets.randbelow(256))
k4g9x2q1
183

Важно: secrets медленнее и не предназначен для больших симуляций. Не используйте random для токенов, ключей или паролей - это угроза безопасности.

Расширенные примеры генерации случайных чисел

1. Генерация надёжного пароля с использованием secrets

Создание пароля длиной 12 символов из букв, цифр и специальных знаков.

Пример
import secrets
import string

alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for _ in range(12))
print(password)
7Fg@3!kP#xY2

Функция secrets.token_urlsafe() генерирует безопасную строку в формате base64, подходящую для токенов.

Пример
import secrets
token = secrets.token_urlsafe(16)  # 16 байт -> примерно 22 символа
print(token)
2l9tZ7Qp8m0c3xR4v5w6

2. Симуляция бросков двух кубиков с суммированием

Моделирование 1000 бросков двух шестигранных кубиков и подсчёт частоты каждой суммы.

Пример
import random
from collections import Counter

def roll_dice(num_rolls=1000):
    results = []
    for _ in range(num_rolls):
        d1 = random.randint(1, 6)
        d2 = random.randint(1, 6)
        results.append(d1 + d2)
    return Counter(results)

freq = roll_dice(1000)
for total, count in sorted(freq.items()):
    print(f"Сумма {total}: {count}")
Сумма 2: 28
Сумма 3: 56
Сумма 4: 83
...
Сумма 12: 25

3. Случайные числа из нормального распределения с визуализацией

Генерируем 1000 чисел со средним 0 и стандартным отклонением 1, выводим гистограмму в текстовом виде.

Пример
import random
import math

mu, sigma = 0, 1
samples = [random.gauss(mu, sigma) for _ in range(1000)]
# простейшая текстовая гистограмма
bins = 20
bin_width = (max(samples) - min(samples)) / bins
for i in range(bins):
    left = min(samples) + i * bin_width
    right = left + bin_width
    count = sum(left <= x < right for x in samples)
    print(f"{left:5.2f} - {right:5.2f}: {'*' * count}")
-3.12 - -2.81: **
-2.81 - -2.50: ****
...
2.81 - 3.12: ***

4. Случайное перемешивание с сохранением исходного списка

Создание копии перемешанного списка без изменения оригинала.

Пример
import random
original = ['A', 'B', 'C', 'D', 'E']
shuffled = random.sample(original, len(original))
print('Оригинал:', original)
print('Перемешан:', shuffled)
Оригинал: ['A', 'B', 'C', 'D', 'E']
Перемешан: ['E', 'C', 'A', 'D', 'B']

5. Использование numpy.random для массивов случайных чисел

Библиотека numpy предоставляет более мощные функции для работы с многомерными массивами. Пример: генерация матрицы 3x4 из равномерно распределённых чисел.

Пример
import numpy as np
# создаём генератор с seed для воспроизводимости
rng = np.random.default_rng(42)
arr = rng.uniform(0, 1, size=(3, 4))
print(arr)
[[0.77395605 0.43887844 0.85859792 0.69736803]
[0.09417735 0.97562235 0.7611397 0.78606431]
[0.12811363 0.45038594 0.37079802 0.92676499]]

Также доступны rng.integers, rng.choice, rng.shuffle для больших объёмов данных с высокой производительностью.

6. Генерация случайных чисел с экспоненциальным распределением

Используем random.expovariate(lambd) для симуляции времени между событиями.

Пример
import random
# среднее время между заявками = 5 минут (lambd = 1/5)
lambd = 1/5
intervals = [random.expovariate(lambd) for _ in range(5)]
print('Интервалы (минут):', [f'{t:.2f}' for t in intervals])
Интервалы (минут): ['1.23', '8.47', '3.01', '0.54', '12.76']

7. Случайный выбор с весами для лотерейного розыгрыша

Участники имеют разное количество билетов, веса пропорциональны числу билетов.

Пример
import random
participants = ['Иван', 'Петр', 'Мария', 'Елена']
tickets = [3, 1, 5, 2]  # веса
winner = random.choices(participants, weights=tickets, k=1)
print('Победитель:', winner[0])
Победитель: Мария

8. Создание своего экземпляра Random для изолированных вычислений

В многопоточных приложениях или для тестов удобно иметь собственный генератор, не влияющий на глобальный.

Пример
import random
my_rng = random.Random(12345)
print('Мои числа:', [my_rng.randint(1, 10) for _ in range(3)])
# глобальный генератор не изменился
print('Глобальные:', [random.randint(1, 10) for _ in range(3)])
Мои числа: [7, 2, 9]
Глобальные: [4, 8, 1]

Генерация случайных чисел - comments

En
Python random (python)