5 проверенных методов создания случайных массивов в Python
Для кого эта статья:
- начинающие и продолжающие разработчики на Python
- специалисты в области данных и машинного обучения
студенты и учащиеся, изучающие программирование и статистику
Случайные числа — неотъемлемый компонент в арсенале каждого Python-разработчика. От простейшей симуляции бросания костей до сложных алгоритмов машинного обучения — умение эффективно генерировать случайные массивы открывает двери к решению бесчисленных задач. 🎲 Многие начинающие программисты застревают на примитивных циклах, не подозревая, что Python предлагает целый спектр элегантных инструментов для создания случайных массивов с точно заданными характеристиками. Давайте разберем пять действительно мощных методов, которые трансформируют этот процесс из рутинного в изящный.
Хотите овладеть искусством работы с данными в Python, включая мастерское создание и манипулирование случайными массивами? Обучение Python-разработке от Skypro поможет вам уверенно писать эффективный код уже через несколько недель. Вы освоите не только базовые, но и продвинутые техники работы с данными, которые высоко ценятся в индустрии. Программа составлена практиками и адаптирована под актуальные требования рынка труда.
Зачем нужны массивы случайных чисел в Python
Генерация случайных чисел — это не просто забавная функция, а важный инструмент, решающий множество практических задач в программировании. Рассмотрим наиболее распространенные сценарии применения:
- Тестирование алгоритмов — проверка работы кода на различных входных данных без необходимости их ручного создания
- Симуляция процессов — моделирование реальных явлений, требующих элемента случайности
- Статистический анализ — создание выборок для проверки гипотез и построения моделей
- Машинное обучение — инициализация весов нейронных сетей, аугментация данных
- Криптография — генерация ключей и солей для шифрования
Максим Леонидов, ведущий Python-разработчик
Помню, как разрабатывал систему рекомендаций для крупного онлайн-магазина. Нам требовалось протестировать алгоритм на разных пользовательских профилях. Вместо того чтобы ждать недели накопления реальных данных, я использовал массивы случайных чисел для симуляции покупательского поведения. Создал генератор профилей с разными характеристиками: возраст (случайные числа от 18 до 80), частота покупок (нормальное распределение со средним 3 раза в месяц), средний чек (логнормальное распределение). Это позволило протестировать систему на "виртуальных" пользователях и обнаружить критические ошибки до релиза. Без инструментов генерации случайных массивов разработка затянулась бы на месяцы.
Прежде чем погрузиться в конкретные методы, важно понимать, что в Python существуют различные подходы к генерации случайных чисел, каждый со своими преимуществами:
| Характеристика | Модуль random | NumPy | Специализированные методы |
|---|---|---|---|
| Скорость работы | Средняя | Высокая | Варьируется |
| Потребление памяти | Низкое | Среднее | Зависит от метода |
| Статистические свойства | Базовые | Расширенные | Специфические |
| Воспроизводимость | Да (с seed) | Да (с seed) | Обычно да |
Правильный выбор метода генерации случайных чисел напрямую влияет на производительность, точность и корректность вашего кода. Теперь рассмотрим конкретные реализации, начиная с базовых подходов. 🚀

Базовый метод: создание массива случайных чисел с random
Модуль random — это встроенная библиотека Python, которая обеспечивает базовую функциональность для генерации случайных чисел. Для начинающих разработчиков этот модуль часто становится отправной точкой при работе со случайностью в коде.
Рассмотрим несколько ключевых способов создания массивов случайных чисел с использованием этого модуля:
- Создание списка целых случайных чисел с помощью
randint():
import random
# Создаем массив из 10 случайных целых чисел в диапазоне от 1 до 100
random_integers = [random.randint(1, 100) for _ in range(10)]
print(random_integers)
# Пример вывода: [42, 68, 35, 1, 70, 25, 79, 59, 63, 65]
- Генерация списка случайных вещественных чисел с помощью
random():
# Массив из 5 случайных чисел от 0 до 1
random_floats = [random.random() for _ in range(5)]
print(random_floats)
# Пример вывода: [0\.23, 0.54, 0.01, 0.89, 0.67]
# Массив из 5 случайных чисел в заданном диапазоне (от 10.5 до 20.5)
scaled_floats = [10\.5 + random.random() * 10 for _ in range(5)]
print(scaled_floats)
# Пример вывода: [15\.32, 20.11, 12.45, 19.67, 10.91]
- Формирование массива с помощью
uniform()для равномерного распределения:
# Массив из 5 чисел в диапазоне от -5.0 до 5.0
uniform_floats = [random.uniform(-5.0, 5.0) for _ in range(5)]
print(uniform_floats)
# Пример вывода: [3\.21, -4.45, 0.89, -2.12, 4.76]
- Создание выборки без повторений с использованием
sample():
# Выбираем 5 случайных чисел из диапазона от 1 до 50 без повторений
unique_sample = random.sample(range(1, 51), 5)
print(unique_sample)
# Пример вывода: [23, 45, 7, 31, 12]
- Генерация случайной выборки с возвращением с помощью
choices():
# Выбираем 10 элементов из заданного списка (с повторениями)
population = ['A', 'B', 'C', 'D', 'E']
weighted_choices = random.choices(population, weights=[10, 1, 1, 1, 1], k=10)
print(weighted_choices)
# Пример вывода: ['A', 'A', 'D', 'A', 'A', 'A', 'A', 'A', 'C', 'A']
Анна Карпова, преподаватель Python
На одном из моих курсов студент создавал простую игру "Угадай число". Он долго бился над механикой, пока я не предложила ему использовать генерацию случайных чисел. Мы начали с базового random.randint(), но затем задумались: а что если создать массив случайных подсказок? Добавили функциональность — игра теперь выдавала подсказки типа "горячо/холодно", генерируя их на основе близости введенного числа к загаданному. Внедрили random.choices() с весами для определения типа подсказки в зависимости от разницы чисел. Результат: из примитивного "больше/меньше" получилась затягивающая игра с элементами стратегии. Студент был в восторге и, что важнее, понял силу случайных массивов в геймдизайне.
Для обеспечения воспроизводимости результатов (что критично для тестирования или научных исследований) используйте random.seed():
# Установка начального значения генератора случайных чисел
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])
# Вывод будет одинаковым при каждом запуске: [81, 14, 3, 94, 35]
# При повторном вызове с тем же seed получим те же числа
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])
# Снова получим: [81, 14, 3, 94, 35]
Преимущества и ограничения модуля random:
| Преимущества | Ограничения |
|---|---|
| Входит в стандартную библиотеку | Относительно медленная работа с большими массивами |
| Прост в использовании | Отсутствие векторизованных операций |
| Не требует установки дополнительных пакетов | Ограниченный набор распределений |
| Хорошая документация | Не оптимизирован для научных вычислений |
Модуль random отлично подходит для простых задач и небольших проектов, но при работе с большими объёмами данных или специфическими распределениями стоит обратить внимание на более специализированные инструменты, как NumPy. 🔄
Оптимизированный подход: генерация случайных чисел с NumPy
NumPy представляет собой значительный шаг вперед по сравнению с базовым модулем random, особенно когда речь идет о работе с большими массивами чисел. Производительность NumPy часто на порядок превышает возможности стандартной библиотеки благодаря оптимизированным С-реализациям и векторизации операций. 🚀
Основные методы генерации случайных массивов в NumPy:
- Создание массива случайных целых чисел с помощью
np.random.randint():
import numpy as np
# Создаем массив из 10 случайных целых чисел от 1 до 100
random_integers = np.random.randint(1, 101, size=10)
print(random_integers)
# Пример вывода: [42 68 35 1 70 25 79 59 63 65]
# Создаем двумерный массив 3x3
random_2d_array = np.random.randint(1, 101, size=(3, 3))
print(random_2d_array)
# Пример вывода:
# [[42 68 35]
# [ 1 70 25]
# [79 59 63]]
- Генерация массива случайных вещественных чисел с
np.random.random():
# Массив из 5 случайных чисел от 0 до 1
random_floats = np.random.random(5)
print(random_floats)
# Пример вывода: [0\.23 0.54 0.01 0.89 0.67]
# Массив размером 2x3 случайных чисел от 0 до 1
random_2d_floats = np.random.random((2, 3))
print(random_2d_floats)
# Пример вывода:
# [[0\.12 0.92 0.45]
# [0\.34 0.75 0.21]]
- Создание массива с заданным распределением — одно из главных преимуществ NumPy:
# Нормальное (Гауссово) распределение с заданным средним и стандартным отклонением
normal_distribution = np.random.normal(loc=0.0, scale=1.0, size=10)
print(normal_distribution)
# Пример вывода: [ 0.12 -0.23 1.45 -0.84 0.44 0.12 -2.3 1.2 0.42 -0.56]
# Экспоненциальное распределение
exponential_distribution = np.random.exponential(scale=1.0, size=10)
print(exponential_distribution)
# Пример вывода: [0\.23 1.54 0.01 2.89 0.67 1.34 0.51 1.23 0.34 2.51]
- Работа с нормализованными распределениями для специфических задач:
# Биномиальное распределение (подбрасывание монеты 10 раз с вероятностью 0.5)
binomial = np.random.binomial(n=10, p=0.5, size=10)
print(binomial)
# Пример вывода: [4 5 3 7 5 6 4 5 6 4]
# Пуассоновское распределение с лямбда = 2
poisson = np.random.poisson(lam=2, size=10)
print(poisson)
# Пример вывода: [2 1 3 0 2 4 1 2 3 2]
- Генерация случайной перестановки с помощью
np.random.permutation():
# Случайная перестановка последовательности от 0 до 9
permutation = np.random.permutation(10)
print(permutation)
# Пример вывода: [7 2 6 9 1 4 0 3 8 5]
# Перемешивание конкретного массива
arr = np.array([1, 2, 3, 4, 5])
shuffled = np.random.permutation(arr)
print(shuffled)
# Пример вывода: [3 1 5 2 4]
Как и в случае со стандартным модулем random, NumPy позволяет установить начальное значение генератора для воспроизводимости результатов:
# Установка начального значения
np.random.seed(42)
print(np.random.randint(1, 101, size=5))
# Вывод будет одинаковым: [51 92 14 71 60]
# Повторная установка того же значения
np.random.seed(42)
print(np.random.randint(1, 101, size=5))
# Снова получим: [51 92 14 71 60]
Начиная с версии NumPy 1.17, рекомендуется использовать более современный подход с Generator:
# Современный подход к установке seed
rng = np.random.Generator(np.random.PCG64(42))
print(rng.integers(1, 101, size=5))
Сравнение производительности NumPy и стандартного модуля random:
import time
import random
import numpy as np
# Тестирование генерации 1 миллиона случайных чисел
size = 1_000_000
# С использованием стандартного модуля random
start_time = time.time()
random_list = [random.randint(1, 100) for _ in range(size)]
standard_time = time.time() – start_time
print(f"Стандартный random: {standard_time:.4f} секунд")
# С использованием NumPy
start_time = time.time()
numpy_array = np.random.randint(1, 101, size=size)
numpy_time = time.time() – start_time
print(f"NumPy random: {numpy_time:.4f} секунд")
print(f"NumPy быстрее в {standard_time/numpy_time:.2f} раз")
# Примерный вывод:
# Стандартный random: 0.1250 секунд
# NumPy random: 0.0089 секунд
# NumPy быстрее в 14.04 раз
Основные преимущества использования NumPy для генерации случайных чисел:
- Высокая производительность — векторизованные операции значительно быстрее циклов
- Широкий выбор распределений — от равномерного до гамма-распределения
- Многомерные массивы — простое создание матриц и тензоров случайных чисел
- Математические операции — удобные функции для статистического анализа сгенерированных данных
- Современный интерфейс — улучшенный генератор случайных чисел в новых версиях
NumPy стал стандартом де-факто для научных вычислений в Python, и его возможности генерации случайных чисел являются незаменимыми для задач машинного обучения, симуляций и статистического анализа. Для большинства серьёзных проектов, где требуется работа со случайными числами, NumPy должен быть вашим первым выбором. 📊
Специализированные решения: массивы случайных чисел для задач
При решении специфических задач базовые методы генерации случайных чисел могут оказаться недостаточными. В таких случаях пригодятся специализированные подходы, адаптированные под конкретные требования. Рассмотрим наиболее полезные и эффективные методы для типичных сценариев. 🛠️
1. Генерация случайных чисел с заданными статистическими свойствами
Иногда требуется создать массив, следующий определенным статистическим закономерностям:
import numpy as np
from scipy import stats
# Создание массива с логнормальным распределением
# Полезно для моделирования цен акций, доходов населения и т.д.
log_normal = np.random.lognormal(mean=0, sigma=1, size=1000)
# Создание массива с распределением Парето (распределение "богатства")
# Характерно для моделирования неравномерных распределений ресурсов
pareto = np.random.pareto(a=3, size=1000)
# Генерация случайных чисел с треугольным распределением
# Полезно при наличии известного минимума, максимума и наиболее вероятного значения
triangular = np.random.triangular(left=1, mode=5, right=10, size=1000)
# Создание коррелированных случайных величин с multivariate_normal
# Важно для финансового моделирования и симуляций
mean = [0, 0]
cov = [[1, 0.8], [0\.8, 1]] # Матрица ковариации определяет корреляцию
multivariate_normal = np.random.multivariate_normal(mean, cov, 1000)
2. Семплирование из пользовательских распределений
Для более сложных случаев можно определить собственное распределение:
from scipy import stats
import numpy as np
# Создаем произвольную функцию плотности вероятности
def custom_pdf(x):
return 0.5 * np.exp(-np.abs(x)) + 0.5 * np.exp(-np.abs(x-2))
# Создаем дискретное приближение с помощью rejection sampling
x = np.linspace(-5, 7, 1000)
y = custom_pdf(x)
max_y = max(y)
samples = []
while len(samples) < 1000:
x_try = np.random.uniform(-5, 7)
y_try = np.random.uniform(0, max_y)
if y_try < custom_pdf(x_try):
samples.append(x_try)
samples = np.array(samples)
3. Генерация случайных булевых массивов
Для моделирования бинарных состояний (например, успех/неудача):
import numpy as np
# Создание массива случайных булевых значений с заданной вероятностью True
probability_true = 0.3
boolean_array = np.random.random(1000) < probability_true
print(f"Доля True: {np.mean(boolean_array)}") # Должно быть около 0.3
4. Случайные массивы для криптографии
Когда требуется криптографически стойкая случайность:
import secrets
import numpy as np
# Генерация криптографически защищенных случайных байтов
random_bytes = secrets.token_bytes(32)
# Преобразование в массив целых чисел
random_crypto_array = np.frombuffer(random_bytes, dtype=np.uint8)
print(random_crypto_array)
# Для получения чисел в определенном диапазоне (например, от 1 до 100)
# с криптографической стойкостью
secure_random_number = secrets.randbelow(100) + 1
# Создание массива таких чисел
secure_array = np.array([secrets.randbelow(100) + 1 for _ in range(20)])
print(secure_array)
5. Воспроизводимые псевдослучайные последовательности для тестирования
Для тестирования часто требуются детерминированные, но выглядящие случайно последовательности:
import hashlib
import numpy as np
def deterministic_random_array(seed, size, min_val=0, max_val=1):
"""Создает детерминированный 'случайный' массив на основе seed."""
random_array = np.zeros(size)
current_seed = seed
for i in range(size):
# Используем хеш для генерации псевдослучайного числа
hash_object = hashlib.sha256((current_seed + str(i)).encode())
hash_hex = hash_object.hexdigest()
# Преобразуем первые 8 символов хеша в число от 0 до 1
value = int(hash_hex[:8], 16) / (16**8)
# Масштабируем значение в нужный диапазон
random_array[i] = min_val + value * (max_val – min_val)
return random_array
# Создаем воспроизводимые массивы для тестирования
test_array_1 = deterministic_random_array("test_seed_1", 10, 1, 100)
test_array_2 = deterministic_random_array("test_seed_1", 10, 1, 100) # Идентично test_array_1
test_array_3 = deterministic_random_array("different_seed", 10, 1, 100) # Другая последовательность
print("Массивы с одинаковым seed идентичны:", np.array_equal(test_array_1, test_array_2))
print("Массивы с разным seed отличаются:", not np.array_equal(test_array_1, test_array_3))
Сравнение различных специализированных методов:
| Метод | Типичные применения | Особенности |
|---|---|---|
| SciPy distributions | Статистическое моделирование, симуляция | Широкий выбор распределений, точная настройка параметров |
| Криптографические генераторы (secrets) | Безопасность, шифрование, токены | Истинная случайность, вычислительно затратные |
| Пользовательские распределения | Специфические научные модели | Максимальная гибкость, требует математического обоснования |
| Детерминистические псевдослучайные последовательности | Тестирование, воспроизводимые эксперименты | 100% воспроизводимость, не подходят для статистических выборок |
| Коррелированные последовательности | Финансовое моделирование, временные ряды | Учитывают взаимосвязи между переменными, сложная настройка |
Выбор специализированного метода генерации случайных массивов зависит от специфики вашей задачи. Важно понимать природу моделируемых процессов и требования к статистическим свойствам генерируемых данных. В сложных случаях может потребоваться консультация со специалистом в области статистики или вероятностного моделирования. 💡
Лайфхаки и советы для работы со случайными числовыми массивами
Эффективная работа со случайными массивами требует не только знания базового синтаксиса, но и понимания тонкостей, которые позволяют избежать типичных ошибок и оптимизировать производительность. Рассмотрим ключевые приёмы и рекомендации, которые значительно упростят ваш код и сделают его более надёжным. 🔧
Оптимизация производительности
- Избегайте циклов при работе с большими массивами. Векторизованные операции NumPy значительно быстрее:
import numpy as np
import time
size = 1_000_000
# Медленный способ (с циклом)
start_time = time.time()
slow_array = []
for _ in range(size):
slow_array.append(np.random.random())
print(f"Время с циклом: {time.time() – start_time:.4f} секунд")
# Быстрый способ (векторизованная операция)
start_time = time.time()
fast_array = np.random.random(size)
print(f"Время с векторизацией: {time.time() – start_time:.4f} секунд")
- Предварительно выделяйте память для массивов, если их размер известен:
# Эффективно – заранее создаем массив нужного размера
result_array = np.zeros(1_000_000)
for i in range(1_000_000):
result_array[i] = np.random.random()
# Менее эффективно – постоянное увеличение размера
inefficient_array = np.array([])
for i in range(1_000_000):
inefficient_array = np.append(inefficient_array, np.random.random())
- Используйте специализированные функции вместо самописных решений:
# Плохо: генерация случайных чисел с нормальным распределением вручную
random_normal_manual = np.mean([np.random.random(10000) for _ in range(12)], axis=0)
# Хорошо: использование встроенной функции
random_normal = np.random.normal(size=10000)
Обеспечение воспроизводимости
- Всегда фиксируйте seed в начале скрипта, если требуется воспроизводимость:
import numpy as np
# Установка глобального seed для всех вычислений
np.random.seed(42)
# Для версий NumPy >=1.17 лучше использовать новый интерфейс
rng = np.random.Generator(np.random.PCG64(42))
- Сохраняйте состояние генератора для длинных вычислений:
# Сохранение текущего состояния генератора
state = np.random.get_state()
# Выполнение некоторых вычислений
random_data = np.random.random(1000)
# Восстановление состояния для воспроизводимости другой части кода
np.random.set_state(state)
same_random_data = np.random.random(1000)
# Проверка: массивы должны быть идентичны
print(np.array_equal(random_data, same_random_data)) # True
Работа с распределениями
- Правильно выбирайте распределение в зависимости от моделируемого процесса:
| Тип данных | Рекомендуемое распределение | Пример в NumPy |
|---|---|---|
| Счетчики, количества (неотрицательные целые) | Пуассоновское, отрицательное биномиальное | np.random.poisson(lam=5, size=1000) |
| Времена ожидания | Экспоненциальное, гамма | np.random.exponential(scale=2.0, size=1000) |
| Измерения с ошибкой (рост, вес) | Нормальное (Гауссово) | np.random.normal(loc=170, scale=10, size=1000) |
| Доходы, цены активов | Логнормальное | np.random.lognormal(mean=0, sigma=1, size=1000) |
| Экстремальные значения (наводнения, максимумы) | Распределение экстремальных значений | np.random.gumbel(loc=0, scale=1, size=1000) |
- Визуализируйте распределение для проверки соответствия ожиданиям:
import matplotlib.pyplot as plt
import numpy as np
# Генерация случайных чисел с разными распределениями
uniform = np.random.uniform(0, 1, 1000)
normal = np.random.normal(0, 1, 1000)
exponential = np.random.exponential(1, 1000)
# Визуализация для проверки
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.hist(uniform, bins=30)
ax1.set_title('Равномерное распределение')
ax2.hist(normal, bins=30)
ax2.set_title('Нормальное распределение')
ax3.hist(exponential, bins=30)
ax3.set_title('Экспоненциальное распределение')
plt.tight_layout()
plt.show()
Обработка и трансформация случайных массивов
- Применяйте функциональные преобразования для получения нужных характеристик:
import numpy as np
# Генерация случайных чисел с нормальным распределением
normal_random = np.random.normal(0, 1, 1000)
# Преобразование в другой диапазон (например, от 5 до 10)
target_min, target_max = 5, 10
scaled_random = target_min + (normal_random – normal_random.min()) * \
(target_max – target_min) / (normal_random.max() – normal_random.min())
print(f"Min: {scaled_random.min()}, Max: {scaled_random.max()}")
# Преобразование в целые числа с сохранением распределения
discrete_random = np.round(scaled_random).astype(int)
print(f"Unique values: {np.unique(discrete_random)}")
- Эффективно генерируйте случайные булевые маски для фильтрации данных:
# Создание массива с 30% случайных True значений
size = 1000
prob_true = 0.3
bool_mask = np.random.random(size) < prob_true
# Применение маски к данным
data = np.arange(size)
filtered_data = data[bool_mask]
print(f"Отфильтровано {len(filtered_data)} элементов из {size}")
Отладка и тестирование
- Проверяйте статистические свойства сгенерированных массивов:
import numpy as np
from scipy import stats
# Генерация случайных чисел с предполагаемым нормальным распределением
random_sample = np.random.normal(loc=0, scale=1, size=1000)
# Базовая статистика
print(f"Среднее: {np.mean(random_sample):.4f} (должно быть около 0)")
print(f"Стандартное отклонение: {np.std(random_sample):.4f} (должно быть около 1)")
# Проверка на нормальность (тест Шапиро-Уилка)
shapiro_test = stats.shapiro(random_sample)
print(f"Тест Шапиро-Уилка: статистика={shapiro_test.statistic:.4f}, p-значение={shapiro_test.pvalue:.4f}")
print(f"Распределение {'вероятно нормальное' if shapiro_test.pvalue > 0.05 else 'не нормальное'}")
- Используйте генерацию с фиксированным seed для тестирования алгоритмов:
import numpy as np
def test_sorting_algorithm():
# Фиксируем seed для воспроизводимости теста
np.random.seed(42)
# Генерируем случайный массив
test_array = np.random.randint(1, 1000, size=100)
# Сортировка нашим алгоритмом
sorted_by_our_algorithm = our_sorting_function(test_array.copy())
# Сортировка встроенным методом (эталон)
expected_result = np.sort(test_array)
# Проверка корректности
assert np.array_equal(sorted_by_our_algorithm, expected_result), "Алгоритм сортировки работает неправильно"
print("Тест прошел успешно!")
Использование этих советов и лайфхаков позволит вам эффективно работать со случайными массивами в Python, избежать типичных ошибок и создавать более надёжный и производительный код. Помните, что правильный выбор метода генерации и корректная обработка случайных данных играют ключевую роль в статистическом моделировании, симуляциях и машинном обучении. 🎯
Овладение техниками создания и манипуляции случайными массивами открывает целый мир возможностей в программировании на Python. От простых игр до сложных моделей машинного обучения — случайные числа служат фундаментом для бесчисленных приложений. Экспериментируйте с различными методами, выбирая наиболее подходящий для конкретной задачи. Помните: эффективная работа со случайностью — это парадоксальным образом контроль над хаосом, превращение непредсказуемого в полезный инструмент для ваших алгоритмов.
Читайте также
- Линейная регрессия в Python: от теории к практическому применению
- 7 мощных методов оценки ML-моделей в Scikit-learn: руководство
- Топ-10 источников датасетов для машинного обучения: полное руководство
- Kaggle: как покорить Эверест машинного обучения для новичков
- Рекомендательные системы: как они работают и почему без них никуда
- Топ-10 онлайн-инструментов для поиска закономерностей в данных
- Создание и фильтрация датафреймов в pandas: руководство для новичков
- Matplotlib для Python: секреты создания профессиональных графиков
- Как сохранить JSON в файл на Python: руководство с примерами кода
- [Как увеличить глубину рекурсии в Python: 5 проверенных методов
Bard: RecursionError в Python: 5 проверенных методов увеличения глубины](/python/kak-uvelichit-glubinu-rekursii-v-python/)