Генерация случайных чисел в Python: все методы и примеры кода
Для кого эта статья:
- Начинающие программисты, интересующиеся Python
- Разработчики, стремящиеся улучшить свои навыки в генерации случайных чисел
Студенты и участники курсов по программированию, желающие освоить практическое применение случайных чисел в проектах
Представьте, что вам нужно смоделировать бросок игральной кости, создать генератор паролей или запрограммировать логику компьютерного противника в игре. Все эти задачи объединяет одно — необходимость генерации случайных чисел. Python предлагает мощный арсенал инструментов для этого, от базового модуля
randomдо высокопроизводительной библиотеки NumPy. В этой статье мы разберём все популярные методы генерации случайных целых чисел, покажем их особенности на реальном коде и научимся выбирать подходящий инструмент для конкретной задачи. 🎲
Заинтересовались программированием на Python и хотите создавать полезные приложения? На курсе Обучение Python-разработке от Skypro вы не только освоите базовые и продвинутые техники работы с случайными числами, но и научитесь создавать полноценные веб-приложения, работать с базами данных и API. Наши студенты уже через 6 месяцев начинают работать junior-разработчиками. Присоединяйтесь!
Основные инструменты генерации случайных чисел в Python
Python предлагает несколько способов генерации случайных чисел, каждый из которых имеет свои преимущества и особенности применения. Рассмотрим основные инструменты и библиотеки, которые помогут нам получить случайные целые числа.
Стандартная библиотека Python включает модуль random, который предоставляет базовые функции для работы со случайными числами. Этот модуль использует алгоритм Mersenne Twister — один из наиболее тестированных и надёжных генераторов псевдослучайных чисел.
Основные функции модуля random для генерации целых чисел:
random.randint(a, b)— возвращает случайное целое число в диапазоне от a до b включительноrandom.randrange(start, stop, step)— возвращает случайно выбранное число из последовательностиrange(start, stop, step)random.choice(sequence)— возвращает случайный элемент из непустой последовательностиrandom.sample(population, k)— возвращает список длиной k из уникальных элементов, выбранных из последовательности population
Для высокопроизводительных вычислений и работы с большими массивами данных лучше использовать библиотеку NumPy, которая предлагает функции для эффективной генерации случайных чисел:
numpy.random.randint(low, high, size)— генерирует массив случайных целых чисел в диапазоне [low, high)numpy.random.choice(a, size, replace, p)— генерирует случайные выборки из заданного одномерного массива
Сравним основные характеристики этих инструментов:
| Библиотека | Скорость работы | Простота использования | Возможности | Типичное применение |
|---|---|---|---|---|
| random (стандартный модуль) | Средняя | Высокая | Базовые функции | Простые скрипты, небольшие проекты |
| NumPy | Высокая | Средняя | Расширенные функции, работа с массивами | Научные вычисления, обработка данных, машинное обучение |
| secrets (Python 3.6+) | Низкая | Средняя | Криптографически стойкие числа | Безопасность, криптография, генерация токенов |
Выбор конкретного инструмента зависит от ваших потребностей. Для большинства задач достаточно стандартного модуля random, но если вы работаете с большими объёмами данных или вам важна производительность, стоит обратить внимание на NumPy.
Михаил Петров, ведущий преподаватель Python На одном из моих первых коммерческих проектов меня попросили реализовать систему генерации случайных купонов для маркетинговой кампании. Я использовал простую функцию randint для создания 6-значных кодов. Всё работало отлично, пока клиент не запросил сразу 100,000 уникальных купонов для массовой рассылки. Мой скрипт на базе random.randint работал больше 30 минут, постоянно проверяя, не сгенерировал ли он дубликат. Перейдя на numpy.random.choice с параметром replace=False, я смог генерировать все 100,000 купонов за считанные секунды. Этот случай научил меня важному принципу: стандартный модуль random прекрасен для простых задач, но когда дело доходит до серьёзных объёмов данных — NumPy незаменим.

Функция randint из модуля random: синтаксис и применение
Функция randint() из модуля random — самый простой и интуитивно понятный способ генерации случайных целых чисел в Python. Её синтаксис максимально прост:
random.randint(a, b)
Где a — нижняя граница диапазона, b — верхняя граница диапазона. Важно отметить, что функция возвращает случайное целое число N, такое что a ≤ N ≤ b. То есть обе границы включаются в диапазон возможных значений.
Для использования функции необходимо сначала импортировать модуль random:
import random
# Генерация случайного числа от 1 до 6 (как бросок кубика)
dice_roll = random.randint(1, 6)
print(f"Выпало: {dice_roll}")
# Генерация случайного числа в диапазоне от -10 до 10
random_number = random.randint(-10, 10)
print(f"Случайное число: {random_number}")
Функция randint() имеет несколько особенностей и ограничений, о которых стоит знать:
- Аргумент
aне может быть большеb, иначе возникнетValueError. - Если аргументы равны (
a == b), функция всегда вернёт это значение. - Функция генерирует псевдослучайные числа, которые при одинаковом начальном состоянии (seed) будут давать одинаковую последовательность.
Последнее свойство можно использовать для создания воспроизводимых результатов, что особенно полезно при тестировании или отладке:
import random
# Устанавливаем seed для воспроизводимости
random.seed(42)
# Эти вызовы всегда будут давать одинаковые числа
print(random.randint(1, 100)) # Например, 81
print(random.randint(1, 100)) # Например, 14
# Если сбросить seed, результаты снова будут предсказуемыми
random.seed(42)
print(random.randint(1, 100)) # Снова 81
Типичные сценарии использования randint():
| Сценарий | Пример кода | Описание |
|---|---|---|
| Моделирование игральных костей | random.randint(1, 6) | Генерация числа от 1 до 6 |
| Случайный выбор в играх | damage = random.randint(5, 15) | Случайный урон в игре |
| Генерация тестовых данных | age = random.randint(18, 65) | Случайный возраст пользователя |
| Моделирование процессов | delay = random.randint(100, 500) | Случайная задержка в миллисекундах |
Если требуется генерировать множество случайных чисел, можно использовать генераторы списков или циклы:
# Генерация списка из 10 случайных чисел от 1 до 100
random_numbers = [random.randint(1, 100) for _ in range(10)]
print(random_numbers)
# Генерация матрицы 3x3 из случайных чисел от 0 до 9
random_matrix = [[random.randint(0, 9) for _ in range(3)] for _ in range(3)]
for row in random_matrix:
print(row)
Функция randint() — это отличный выбор для большинства простых случаев генерации случайных целых чисел. Она проста в использовании, интуитивно понятна и достаточно эффективна для большинства повседневных задач программирования. 🎯
Работа с randrange и choice для получения целых чисел
Помимо randint(), модуль random предлагает две другие мощные функции для генерации случайных целых чисел: randrange() и choice(). Они предоставляют более гибкие возможности и могут быть более подходящими для определённых сценариев.
Функция randrange()
Функция randrange() позволяет выбрать случайное число из диапазона, определённого функцией range(). Синтаксис этой функции:
random.randrange([start], stop, [step])
Где:
start(опционально) — начало диапазона, по умолчанию 0stop— конец диапазона (не включается)step(опционально) — шаг, по умолчанию 1
Важное отличие от randint() заключается в том, что верхняя граница stop не включается в диапазон возможных значений. Фактически, randint(a, b) эквивалентно randrange(a, b+1).
Примеры использования randrange():
import random
# Случайное число от 0 до 9 (10 не включается)
print(random.randrange(10)) # Эквивалентно random.randint(0, 9)
# Случайное число от 1 до 10 (11 не включается)
print(random.randrange(1, 11)) # Эквивалентно random.randint(1, 10)
# Случайное чётное число от 0 до 100
print(random.randrange(0, 101, 2))
# Случайное нечётное число от 1 до 99
print(random.randrange(1, 100, 2))
Функция randrange() особенно полезна, когда нам нужны случайные числа с определённым шагом или когда мы хотим соответствовать логике функции range().
Функция choice()
Функция choice() выбирает случайный элемент из непустой последовательности (список, строка, кортеж и т.д.). Синтаксис:
random.choice(sequence)
Хотя эта функция может работать с любыми типами данных в последовательности, мы можем использовать её для получения случайных целых чисел, предварительно создав последовательность чисел:
import random
# Выбор случайного числа из списка
numbers = [10, 20, 30, 40, 50]
print(random.choice(numbers))
# Выбор случайной цифры из строки
digit = random.choice("0123456789")
print(int(digit)) # Преобразуем в целое число
# Выбор случайного элемента из диапазона
print(random.choice(range(1, 101))) # Случайное число от 1 до 100
Функция choice() особенно удобна, когда нам нужно выбрать случайное число из заранее определённого набора значений.
Анна Соколова, Python-разработчик Однажды на хакатоне нам потребовалось создать игру "Угадай число" с нестандартным уровнем сложности. Вместо обычного диапазона, мы решили, что компьютер будет загадывать числа только определённой структуры. Изначально я использовала
randint, а затем проверяла, подходит ли число под наши требования. Это работало, но иногда приходилось генерировать десятки чисел, прежде чем находилось подходящее — неэффективно и медленно. Решение пришло, когда я вспомнила проrandrangeс параметром step. Для "средних" чисел от 1 до 100, кратных 5, достаточно было использовать:PythonСкопировать кодsecret_number = random.randrange(5, 101, 5)А для "сложных" чисел — простых чисел до 100 — мы создали список заранее:
PythonСкопировать кодprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] secret_number = random.choice(primes)Код стал не только быстрее, но и понятнее. С тех пор я всегда думаю, можно ли задачу решить с помощью
randrangeилиchoice, прежде чем использоватьrandintс дополнительными проверками.
Комбинирование функций
Часто для более сложных сценариев полезно комбинировать различные функции модуля random:
import random
# Выбор случайного количества случайных чисел
count = random.randint(3, 7) # Случайное количество от 3 до 7
numbers = [random.randrange(1, 101) for _ in range(count)]
print(f"Выбрано {count} чисел: {numbers}")
# Выбор случайного количества уникальных чисел
unique_count = random.randint(3, 7)
unique_numbers = random.sample(range(1, 101), unique_count)
print(f"Выбрано {unique_count} уникальных чисел: {unique_numbers}")
# Генерация случайных данных для тестирования
test_data = []
for _ in range(5):
age = random.randint(18, 65)
salary = random.randrange(30000, 200001, 1000) # Шаг 1000
experience = random.choice([0, 1, 2, 3, 5, 7, 10, 15])
test_data.append({"age": age, "salary": salary, "experience": experience})
for data in test_data:
print(data)
Выбор между randint(), randrange() и choice() зависит от конкретной задачи и от того, как вы предпочитаете определять диапазон случайных чисел. Все три функции основаны на одном и том же генераторе псевдослучайных чисел, поэтому с точки зрения качества случайности они эквивалентны. 🎮
Производительная генерация случайных чисел с numpy
Когда речь заходит о высокопроизводительных вычислениях или работе с большими объёмами данных, библиотека NumPy становится незаменимым инструментом. Её модуль numpy.random предлагает эффективные функции для генерации случайных чисел, которые значительно быстрее стандартного модуля random при работе с массивами.
Для начала работы с NumPy необходимо установить библиотеку (если она ещё не установлена) и импортировать её:
# Установка: pip install numpy
import numpy as np
Функция numpy.random.randint()
Основная функция для генерации случайных целых чисел в NumPy — randint(). Её синтаксис:
numpy.random.randint(low, high=None, size=None, dtype=int)
Где:
low— нижняя граница диапазона (включительно)high— верхняя граница диапазона (не включительно). Если не указана, тоlowстановится 0, аhigh— значениемlowsize— размер или форма выходного массиваdtype— тип данных выходного массива
Важное отличие от random.randint(): верхняя граница high не включается в диапазон возможных значений, как в функции random.randrange().
Примеры использования:
import numpy as np
# Генерация одного случайного числа от 0 до 9
print(np.random.randint(10))
# Генерация одного случайного числа от 1 до 10
print(np.random.randint(1, 11))
# Генерация массива из 5 случайных чисел от 1 до 100
print(np.random.randint(1, 101, size=5))
# Генерация двумерного массива 3x3 из случайных чисел от 0 до 9
print(np.random.randint(0, 10, size=(3, 3)))
Функция numpy.random.choice()
Функция choice() в NumPy похожа на аналогичную функцию в стандартном модуле random, но предлагает дополнительные возможности:
numpy.random.choice(a, size=None, replace=True, p=None)
Где:
a— одномерный массив или целое число. Если целое число, то создаётся массивnp.arange(a)size— размер или форма выходного массиваreplace— если True, то элементы могут повторяться; если False, то все элементы будут уникальнымиp— массив вероятностей для каждого элемента вa
Примеры использования:
import numpy as np
# Выбор случайного числа от 0 до 9
print(np.random.choice(10))
# Выбор 5 случайных чисел от 0 до 9 с повторениями
print(np.random.choice(10, size=5))
# Выбор 5 уникальных чисел от 0 до 9 (без повторений)
print(np.random.choice(10, size=5, replace=False))
# Выбор с заданными вероятностями (смещённое распределение)
# Числа 0-4 имеют вероятность 0.1, а числа 5-9 — вероятность 0.1
probabilities = np.array([0\.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1])
print(np.random.choice(10, size=10, p=probabilities))
# Выбор из пользовательского массива
custom_array = np.array([10, 20, 30, 40, 50])
print(np.random.choice(custom_array, size=3))
Производительность NumPy
Главное преимущество NumPy — его производительность при работе с большими объёмами данных. Сравним скорость генерации большого количества случайных чисел между стандартным модулем random и NumPy:
import random
import numpy as np
import time
# Количество чисел для генерации
n = 1_000_000
# Измерение времени для стандартного модуля random
start_time = time.time()
random_numbers = [random.randint(1, 100) for _ in range(n)]
standard_time = time.time() – start_time
print(f"Стандартный random: {standard_time:.4f} секунд")
# Измерение времени для NumPy
start_time = time.time()
numpy_numbers = np.random.randint(1, 101, size=n)
numpy_time = time.time() – start_time
print(f"NumPy random: {numpy_time:.4f} секунд")
# Сравнение
print(f"NumPy быстрее в {standard_time / numpy_time:.2f} раз")
Результаты этого теста показывают, что NumPy может быть в десятки раз быстрее стандартного модуля random при работе с большими массивами данных.
Дополнительные возможности NumPy для генерации случайных чисел
NumPy предоставляет и другие полезные функции для работы со случайными числами:
np.random.seed()— установка seed для воспроизводимости результатовnp.random.permutation()— случайная перестановка последовательностиnp.random.shuffle()— перемешивание последовательности на месте
Пример использования этих функций:
import numpy as np
# Установка seed для воспроизводимости
np.random.seed(42)
print(np.random.randint(1, 101, size=5))
# Сброс seed для получения тех же результатов
np.random.seed(42)
print(np.random.randint(1, 101, size=5)) # Те же числа
# Случайная перестановка последовательности
arr = np.arange(10) # [0, 1, 2, ..., 9]
print(np.random.permutation(arr))
# Перемешивание на месте
np.random.shuffle(arr)
print(arr) # Исходный массив изменён
NumPy также предлагает различные распределения для генерации случайных чисел. Хотя большинство из них генерируют вещественные числа, некоторые могут быть полезны для генерации целых чисел с определёнными статистическими свойствами:
import numpy as np
# Биномиальное распределение (целые числа)
# Моделирует количество успехов в n испытаниях с вероятностью p
# Например, количество выпадений "орла" при 10 подбрасываниях монеты
print(np.random.binomial(n=10, p=0.5, size=5))
# Пуассоновское распределение (целые числа)
# Моделирует количество событий за фиксированный интервал времени
# Например, количество клиентов, прибывающих в магазин за час
print(np.random.poisson(lam=5, size=5)) # lam — среднее значение
NumPy — идеальный выбор для задач, требующих генерации большого количества случайных чисел или сложных статистических расчетов. Его эффективность и широкие возможности делают его незаменимым инструментом для научных вычислений, анализа данных и машинного обучения. 🧮
Практические задачи с использованием случайных чисел
Теперь, когда мы рассмотрели различные методы генерации случайных целых чисел, давайте применим полученные знания к решению практических задач. Эти примеры помогут вам увидеть, как использовать случайные числа в реальных проектах.
1. Моделирование игры в кости
Создадим простую симуляцию игры в кости, где два игрока бросают кубики, и побеждает тот, кто выбросил большую сумму:
import random
def roll_dice(num_dice=2):
"""Бросает указанное количество костей и возвращает сумму"""
return sum(random.randint(1, 6) for _ in range(num_dice))
def dice_game(num_rounds=5):
"""Симуляция игры в кости из нескольких раундов"""
player1_score = 0
player2_score = 0
for round_num in range(1, num_rounds + 1):
player1_roll = roll_dice()
player2_roll = roll_dice()
print(f"Раунд {round_num}: Игрок 1 выбросил {player1_roll}, Игрок 2 выбросил {player2_roll}")
if player1_roll > player2_roll:
player1_score += 1
print("Игрок 1 выиграл раунд")
elif player2_roll > player1_roll:
player2_score += 1
print("Игрок 2 выиграл раунд")
else:
print("Ничья в раунде")
print(f"\nИтоговый счёт: Игрок 1 – {player1_score}, Игрок 2 – {player2_score}")
if player1_score > player2_score:
print("Игрок 1 победил в игре!")
elif player2_score > player1_score:
print("Игрок 2 победил в игре!")
else:
print("Игра закончилась вничью!")
# Запуск игры
dice_game()
2. Генератор паролей
Создадим функцию для генерации случайных паролей с заданными параметрами:
import random
import string
def generate_password(length=12, use_digits=True, use_special_chars=True):
"""Генерирует случайный пароль с заданными параметрами"""
# Определяем набор символов для пароля
chars = string.ascii_letters # Буквы в обоих регистрах
if use_digits:
chars += string.digits # Добавляем цифры
if use_special_chars:
chars += string.punctuation # Добавляем специальные символы
# Генерируем пароль
password = ''.join(random.choice(chars) for _ in range(length))
return password
# Генерация паролей с разными параметрами
simple_password = generate_password(length=8, use_digits=False, use_special_chars=False)
medium_password = generate_password(length=10, use_digits=True, use_special_chars=False)
strong_password = generate_password(length=16, use_digits=True, use_special_chars=True)
print(f"Простой пароль: {simple_password}")
print(f"Средний пароль: {medium_password}")
print(f"Сложный пароль: {strong_password}")
3. Генерация тестовых данных
Создадим функцию для генерации тестовых данных о пользователях для тестирования приложения:
import random
import numpy as np
from datetime import datetime, timedelta
def generate_user_data(num_users=10):
"""Генерирует тестовые данные о пользователях"""
# Возможные значения для данных
first_names = ["Иван", "Мария", "Александр", "Екатерина", "Дмитрий", "Ольга", "Сергей", "Анна", "Андрей", "Елена"]
last_names = ["Иванов", "Петров", "Сидоров", "Смирнов", "Кузнецов", "Попов", "Васильев", "Соколов", "Михайлов", "Новиков"]
cities = ["Москва", "Санкт-Петербург", "Новосибирск", "Екатеринбург", "Казань", "Нижний Новгород", "Самара", "Омск", "Ростов-на-Дону", "Уфа"]
users = []
for _ in range(num_users):
# Генерируем случайные данные для пользователя
user = {
"first_name": random.choice(first_names),
"last_name": random.choice(last_names),
"age": random.randint(18, 65),
"city": random.choice(cities),
"salary": random.randrange(30000, 200001, 5000),
"is_active": random.choice([True, False]),
"registration_date": (datetime.now() – timedelta(days=random.randint(1, 365))).strftime("%Y-%m-%d"),
"last_login": (datetime.now() – timedelta(days=random.randint(0, 30))).strftime("%Y-%m-%d"),
"visits": np.random.poisson(10, 1)[0] # Среднее количество посещений – 10
}
users.append(user)
return users
# Генерация и вывод тестовых данных
test_users = generate_user_data(5)
for i, user in enumerate(test_users, 1):
print(f"Пользователь {i}:")
for key, value in user.items():
print(f" {key}: {value}")
print()
4. Симуляция Монте-Карло для расчёта числа π
Используем метод Монте-Карло для приближенного вычисления числа π, генерируя случайные точки в квадрате и проверяя, попадают ли они в вписанный круг:
import random
import numpy as np
import time
def estimate_pi_standard_random(num_points=1000000):
"""Оценка числа π методом Монте-Карло с использованием стандартного модуля random"""
points_inside_circle = 0
for _ in range(num_points):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
# Проверяем, находится ли точка внутри четверти круга с центром в (0,0) и радиусом 1
if x*x + y*y <= 1:
points_inside_circle += 1
# Площадь четверти круга / площадь квадрата = π/4
return 4 * points_inside_circle / num_points
def estimate_pi_numpy(num_points=1000000):
"""Оценка числа π методом Монте-Карло с использованием NumPy"""
# Генерируем случайные координаты x и y от 0 до 1
x = np.random.random(num_points)
y = np.random.random(num_points)
# Вычисляем расстояние от начала координат
distances = x*x + y*y
# Подсчитываем точки внутри круга
points_inside_circle = np.sum(distances <= 1)
return 4 * points_inside_circle / num_points
# Сравнение методов
print("Метод Монте-Карло для оценки числа π")
print(f"Реальное значение π: {np.pi}\n")
for num_points in [10000, 100000, 1000000]:
print(f"Количество точек: {num_points}")
# Стандартный random
start_time = time.time()
pi_standard = estimate_pi_standard_random(num_points)
standard_time = time.time() – start_time
print(f"Стандартный random: π ≈ {pi_standard:.6f}, ошибка = {abs(pi_standard – np.pi):.6f}, время = {standard_time:.4f} с")
# NumPy
start_time = time.time()
pi_numpy = estimate_pi_numpy(num_points)
numpy_time = time.time() – start_time
print(f"NumPy: π ≈ {pi_numpy:.6f}, ошибка = {abs(pi_numpy – np.pi):.6f}, время = {numpy_time:.4f} с")
print(f"NumPy быстрее в {standard_time / numpy_time:.2f} раз\n")
5. Простая игра "Угадай число"
Создадим интерактивную игру, где компьютер загадывает число, а пользователь пытается его угадать:
import random
def guess_number_game():
"""Простая игра 'Угадай число'"""
# Компьютер загадывает число от 1 до 100
secret_number = random.randint(1, 100)
attempts = 0
max_attempts = 10
print("Добро пожаловать в игру 'Угадай число'!")
print(f"Я загадал число от 1 до 100. У тебя есть {max_attempts} попыток, чтобы угадать его.")
while attempts < max_attempts:
try:
# Получаем предположение от пользователя
guess = int(input(f"Попытка {attempts + 1}/{max_attempts}. Введите число: "))
# Увеличиваем счётчик попыток
attempts += 1
# Проверяем предположение
if guess < secret_number:
print("Больше!")
elif guess > secret_number:
print("Меньше!")
else:
print(f"Поздравляю! Вы угадали число {secret_number} за {attempts} попыток.")
return
except ValueError:
print("Пожалуйста, введите корректное целое число.")
print(f"Увы, вы исчерпали все попытки. Загаданное число было: {secret_number}")
# Запуск игры
# guess_number_game() # Раскомментируйте для игры
Эти практические примеры демонстрируют, как случайные числа могут быть использованы в различных сценариях: от простых игр до научных расчётов и генерации тестовых данных. Выбор конкретного метода генерации зависит от требований к производительности, статистическим свойствам случайных чисел и удобству использования. 🚀
Случайные числа — это неотъемлемая часть программирования, от простых игр до сложных алгоритмов машинного обучения. Мы рассмотрели основные методы генерации случайных целых чисел в Python, начиная с простой функции
randintи заканчивая высокопроизводительными решениями на основе NumPy. Главный урок — всегда выбирайте инструмент, соответствующий вашей задаче: для простых скриптов достаточно стандартного модуляrandom, а для научных вычислений и работы с большими массивами данных лучше использовать NumPy. Понимание различных подходов к генерации случайных чисел и их особенностей поможет вам писать более эффективный и элегантный код.