На примере игрового инвентаря разбираемся, когда важен порядок, когда — имя свойства и почему структуры часто используют вместе.
Сначала вопрос, потом структура
Есть три найденных предмета: ключ, карта и фонарь. Если нужно перебрать их по порядку, подойдёт список. Если нужно хранить характеристики игрока — имя, запас здоровья и уровень — удобен словарь: у каждого значения есть ключ.
Это не соревнование двух способов. Выбор зависит от вопроса к данным. «Что лежит на второй позиции?» и «Какой у игрока запас здоровья?» устроены по-разному.
Список: значения по позициям
Индексы списка начинаются с нуля. В примере items[0] вернёт ключ, а items[1] — карту. Метод append добавит предмет в конец. Если предметы повторяются, список сохранит оба экземпляра.
Позиция не является постоянным именем предмета. Если удалить первый элемент, следующий займёт его место. Поэтому нельзя хранить номер позиции как вечный идентификатор вещи, если список будет изменяться.
items = ["ключ", "карта", "фонарь"]
items.append("монета")
print(items[1]) # карта
for item in items:
print(item)Словарь: значения по ключам
В словаре можно обратиться к характеристике по понятному имени. player["health"] даст здоровье без необходимости помнить, что оно было «вторым значением». Повторное присваивание тому же ключу заменит значение.
Если player["mana"] не существует, обращение через квадратные скобки вызовет KeyError. Метод get позволяет указать значение по умолчанию. Это полезно для необязательного поля, но не должно скрывать опечатку в обязательном ключе.
player = {"name": "Лис", "health": 100, "level": 1}
player["health"] = 80
print(player["health"]) # 80
print(player.get("mana", 0)) # 0Список словарей: несколько предметов с характеристиками
Теперь у каждой вещи есть не только название, но и количество. Один словарь описывает предмет, а список объединяет предметы. Получается структура, которую удобно перебирать.
В примере цикл печатает две строки: «ключ 1» и «монета 12». Значения count — числа, поэтому их можно складывать. Если записать количество как строку, дальнейшие вычисления потребуют преобразования.
inventory = [
{"name": "ключ", "count": 1},
{"name": "монета", "count": 12},
]
for item in inventory:
print(item["name"], item["count"])Что произойдёт при копировании
Запись other = items не создаёт независимый список: оба имени ссылаются на один объект. Если затем добавить предмет через other, он появится и при чтении items. Для простого списка можно создать поверхностную копию через items.copy().
Во вложенных структурах поверхностная копия сохраняет ссылки на внутренние объекты. Это отдельная причина неожиданностей: внешний список новый, а словари внутри могут оставаться общими. Не делай вывод об независимости данных только по тому, что переменные называются по-разному.