Python
Как создать список заданной длины в Python
Список заданной длины нужен, когда вы заранее знаете количество элементов: места под оценки, поле игры, счетчики, пустые значения для заполнения
Разберем несколько способов создать список нужной длины: пустые места через None, числа через range, значения через генератор и двумерную заготовку без общей ссылки на одну строку
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Базовый пример
Самый простой вариант:
n = 5
items = [None] * n
print(items)
Так удобно создать список-заготовку, если элементы пока неизвестны
Разбор по шагам
Для списка фиксированной длины сначала решите, чем будут заполнены места. Если значения пока неизвестны, подойдет [None] * n. Если нужны числа по порядку, лучше list(range(n)). Если каждое значение считается отдельно, используйте генератор списка
С двумерными списками нельзя бездумно писать [[0] cols] rows: так несколько строк будут ссылаться на один и тот же внутренний список. Для таблицы используйте генератор с вложенным списком, чтобы каждая строка была самостоятельной
Практические варианты
Список чисел
n = 5
numbers = list(range(n))
print(numbers)
Список через генератор
n = 5
squares = [i * i for i in range(n)]
print(squares)
Двумерный список
rows = 3
cols = 4
field = [[0 for _ in range(cols)] for _ in range(rows)]
print(field)
Частые ошибки
Не создавайте двумерный список через [[0] cols] rows, если планируете менять отдельные ячейки. Внутренние строки будут ссылаться на один и тот же список
Как проверить результат
- запустить код на обычном примере
- проверить пустой список
- проверить список из одного элемента
- проверить повторы
- объяснить, меняется исходный список или создается новый
- вынести действие в функцию, если оно повторяется
Заполнение одним значением
size = 4
flags = [False] * size
print(flags)
Для неизменяемых значений вроде чисел, строк, None и False такой способ безопасен
Заполнение разными значениями
size = 5
numbers = [i + 1 for i in range(size)]
print(numbers)
Генератор списка нужен, когда каждый элемент зависит от индекса
Заготовка для результатов
names = ["Анна", "Илья", "Мария"]
lengths = [0] * len(names)
for index, name in enumerate(names):
lengths[index] = len(name)
print(lengths)
Такой прием помогает, когда нужно сохранить результат на той же позиции, что и исходный элемент
Практика на закрепление
Практический сценарий — подготовить список счетчиков для нескольких дней недели
days = 7
visits = [0] * days
visits[0] += 3
visits[1] += 5
print(visits)
Если значение зависит от индекса, используйте генератор:
days = 7
labels = [f"day_{index + 1}" for index in range(days)]
print(labels)
Для вложенных списков всегда создавайте каждую строку отдельно:
rows = 2
cols = 3
table = [[None for _ in range(cols)] for _ in range(rows)]
table[0][0] = "start"
print(table)
Проверьте, что изменение table[0][0] не поменяло table[1][0]. Если поменяло, значит строки были созданы неправильно
Практика: заготовка для результатов
Сделайте список результатов на неделю. Сначала в нем семь пустых мест, потом вы заполняете нужный день значением. Такой прием встречается в расписаниях, дневниках привычек и простых отчетах
def create_week():
return [None for _ in range(7)]
def set_day_result(results, day_index, value):
if day_index < 0 or day_index >= len(results):
return False
results[day_index] = value
return True
week = create_week()
print(set_day_result(week, 0, "готово"))
print(set_day_result(week, 10, "ошибка"))
print(week)
Для двумерной заготовки используйте вложенный генератор. Так каждая строка будет отдельным списком, и изменение одной строки не испортит остальные
Почему None часто лучше нуля
Когда список создается как заготовка, важно выбрать понятное пустое значение. Ноль может быть настоящим результатом: например, ноль продаж, ноль ошибок или ноль баллов. Поэтому для пустого места часто лучше использовать None
results = [None for _ in range(3)]
results[0] = 0
print(results)
В этом примере видно, что None означает «значения еще нет», а 0 означает реальный результат. Такая разница помогает не перепутать пустую ячейку с честным нулем. Для расписаний, таблиц результатов и временных слотов это особенно важно
Ошибка с общей строкой в матрице
Когда нужно создать таблицу, не умножайте внутренний список на количество строк. Иначе все строки будут ссылаться на один объект, и изменение одной строки изменит остальные
bad = [[0] * 3] * 2
bad[0][0] = 9
print(bad)
good = [[0 for _ in range(3)] for _ in range(2)]
good[0][0] = 9
print(good)
Для обычного одномерного списка умножение часто нормально. Для вложенных списков безопаснее генератор, который создает каждую строку отдельно
Итоговая практика: список мест для расписания
Создайте список слотов на день и функцию записи в конкретный слот. Это типичный пример, где нужна заранее известная длина
def create_slots(count):
return [None for _ in range(count)]
def reserve_slot(slots, index, value):
if index < 0 or index >= len(slots):
return False
if slots[index] is not None:
return False
slots[index] = value
return True
slots = create_slots(4)
print(reserve_slot(slots, 1, "созвон"))
print(reserve_slot(slots, 1, "повтор"))
print(reserve_slot(slots, 10, "ошибка"))
print(slots)
Такой пример закрепляет длину списка, индексы, пустые значения и проверку занятого места
Если длина списка приходит от пользователя, проверьте ее до создания списка. Отрицательная длина не имеет смысла, слишком большая длина может занять лишнюю память, а ноль означает пустую заготовку. В маленькой учебной функции достаточно вернуть пустой список для некорректного значения или показать сообщение об ошибке. Так тема длины сразу связывается с безопасной обработкой ввода
Для закрепления измените пример со слотами: создайте не четыре места, а количество, которое приходит в переменной count. Затем проверьте count = 0, count = 1 и обычное значение вроде count = 5. Такая маленькая проверка быстро показывает, правильно ли программа работает с длиной, а не только с одним заранее выбранным примером