Генератор случайных чисел Python: функции, примеры, проблемы
Генерация случайных чисел в Python: обзор модуля random
Основной способ получения случайного целого числа в заданном диапазоне
Наиболее часто используемый метод для генерации случайного целого числа в Python - random.randint(a, b). Он возвращает целое число N, такое что a ≤ N ≤ b. Это простое и эффективное решение для большинства задач.
import random
# Случайное число от 1 до 10
number = random.randint(1, 10)
print(number)
Import random python (импорт модуля random в python)
7
Python случайное число (случайное число в python)
Возможные проблемы:
- Функция работает только с целыми числами. Попытка передать дробные значения вызовет TypeError.
- Если a > b, возникает ValueError. Всегда проверяйте порядок аргументов.
- Псевдослучайные числа не подходят для криптографических целей.
Как получить случайное число с плавающей точкой в заданном диапазоне?
Для генерации случайного вещественного числа используется random.uniform(a, b). Результат может быть равен a или b (с учётом погрешностей округления), и распределён равномерно на отрезке [a, b].
import random
value = random.uniform(0.5, 2.5)
print(value)
Python random number (генерация случайного числа random python)
1.834560123456789
Из-за ограниченной точности чисел с плавающей точкой границы включаются не всегда. Например, random.uniform(0, 1) может вернуть 1.0, но это крайне редко. Если требуется строгое исключение верхней границы, используют random.random() * (b - a) + a.
Как выбрать случайный элемент из списка?
Функция random.choice(seq) возвращает один случайный элемент непустой последовательности (список, кортеж, строка).
import random
fruits = ['яблоко', 'банан', 'вишня', 'апельсин']
print(random.choice(fruits))
банан
Если последовательность пуста, возникает IndexError. Всегда проверяйте длину перед вызовом.
Как получить несколько случайных чисел без повторений?
random.sample(population, k) возвращает список длиной k из уникальных элементов, выбранных из population. Исходная последовательность не изменяется.
import random
numbers = [1, 2, 3, 4, 5, 6]
sample = random.sample(numbers, 3)
print(sample)
[4, 1, 6]
Если k больше длины population, возникает ValueError. Для выборки с возможными повторениями используйте random.choices.
Как сгенерировать случайное число с нормальным распределением?
Для моделирования случайных величин, подчиняющихся нормальному закону, применяется random.gauss(mu, sigma), где mu - среднее, sigma - стандартное отклонение.
import random
# Средний рост 170 см, отклонение 10 см
height = random.gauss(170, 10)
print(round(height, 1))
165.3
Функция не доступна в Python 2 (только random.normalvariate). В Python 3 обе работают аналогично. Разница в алгоритме - gauss быстрее, но не потокобезопасна.
Как получить криптостойкое случайное число?
Для задач, требующих безопасности (пароли, токены), модуль random не подходит. Используйте secrets из стандартной библиотеки. Например, secrets.randbelow(n) возвращает случайное целое из [0, n).
import secrets
# Случайное число от 0 до 99
secure_number = secrets.randbelow(100)
print(secure_number)
42
Модуль secrets медленнее random, но обеспечивает криптографическую стойкость. Не применяйте для моделирования или игр.
Как перемешать список случайным образом?
Функция random.shuffle(x) изменяет исходный список (кортеж или строку нельзя, только список). Она переставляет элементы в случайном порядке на месте.
import random
cards = ['A', 'K', 'Q', 'J', '10']
random.shuffle(cards)
print(cards)
['10', 'K', 'Q', 'A', 'J']
Метод не возвращает новый список, а изменяет переданный. Если нужна случайная перестановка без изменения оригинала, используйте random.sample(x, len(x)).
Расширенные примеры и нестандартные применения
Генерация случайного пароля
Комбинируем буквы, цифры и символы с помощью random.choice и строки констант из модуля string.
import random
import string
def generate_password(length=12):
chars = string.ascii_letters + string.digits + string.punctuation
return ''.join(random.choice(chars) for _ in range(length))
print(generate_password(16))
zX8!kL3@qR5#vN9a
Пояснение:
Собираем всевозможные символы, затем делаем выборку с повторениями. Для криптостойкости лучше использовать secrets.choice.
Симуляция броска игральной кости с произвольным числом граней
import random
def dice_roll(sides=6):
return random.randint(1, sides)
print('Результат броска D20:', dice_roll(20))
Результат броска D20: 17
Простая функция, демонстрирующая гибкость randint.
Воспроизводимость результатов с seed
Устанавливая начальное зерно, можно повторять одинаковую последовательность случайных чисел для отладки или тестирования.
import random
random.seed(42)
print('Первые три числа:', [random.randint(1, 100) for _ in range(3)])
random.seed(42) # сброс зерна
print('Те же числа:', [random.randint(1, 100) for _ in range(3)])
Первые три числа: [82, 15, 4] Те же числа: [82, 15, 4]
Ошибка:
Если вызвать seed внутри цикла, числа могут повторяться. Следует устанавливать зерно один раз.
Случайная выборка с весами (random.choices)
Используется, когда одни элементы должны появляться чаще других.
import random
colors = ['красный', 'зеленый', 'синий']
weights = [0.5, 0.3, 0.2] # красный - 50%, зеленый - 30%, синий - 20%
result = random.choices(colors, weights=weights, k=10)
print(result)
['красный', 'синий', 'красный', 'зеленый', 'красный', 'красный', 'зеленый', 'красный', 'синий', 'зеленый']
Параметр cum_weights позволяет задать накопленные веса.
Генерация чисел с нормальным распределением для моделирования
import random
# Моделирование роста 100 человек
heights = [random.gauss(170, 7) for _ in range(100)]
avg = sum(heights) / len(heights)
print('Средний рост выборки:', round(avg, 1))
Средний рост выборки: 170.2
При большом числе испытаний среднее приближается к заданному значению mu.
Потокобезопасная генерация с Random экземпляром
Если приложение использует многопоточность, лучше создать собственный экземпляр random.Random для каждого потока, чтобы избежать гонок.
import random
import threading
def worker():
local_rng = random.Random()
local_rng.seed(hash(threading.current_thread().name))
print(threading.current_thread().name, local_rng.randint(1, 100))
threads = [threading.Thread(target=worker) for _ in range(3)]
for t in threads:
t.start()
for t in threads:
t.join()
Thread-1 67 Thread-2 23 Thread-3 88
Каждый поток использует свой генератор, что исключает блокировки.