Генерация случайных чисел с помощью 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]