В Python есть четыре базовых структуры данных для хранения коллекций: списки, кортежи, множества и словари. Они решают похожие задачи (хранить много значений), но устроены по‑разному и подходят для разных сценариев. Разберём, в каких случаях брать каждую из них, с примерами и без лишних слов.
Списки (list): когда важен порядок и нужна изменяемость
Список — это упорядоченная изменяемая коллекция. Элементы идут в том порядке, в котором вы их добавили, и этот порядок сохраняется. Список можно менять: добавлять, удалять, изменять элементы.
Объявление:
numbers = [10, 20, 30] names = ["Анна", "Борис", "Виктор"] mixed = [1, "два", 3.0, True]
Типичные операции:
numbers.append(40) # [10, 20, 30, 40] numbers[0] = 5 # [5, 20, 30, 40] del numbers[1] # [5, 30, 40]
Когда использовать:
- Нужно хранить последовательность элементов в определённом порядке.
- Коллекция будет меняться: добавлять/удалять элементы, обновлять значения.
- Нужны операции по индексам: взять первый, последний, срез.
Пример: список задач, где порядок важен, а задачи добавляются и выполняются:
tasks = ["купить хлеб", "позвонить клиенту", "проверить почту"] tasks.append("заполнить отчёт") completed = tasks.pop(0) # первая задача выполнена
Кортежи (tuple): когда порядок важен, но менять не нужно
Кортеж — это упорядоченная неизменяемая коллекция. Порядок есть, а менять элементы нельзя. Это даёт предсказуемость и позволяет использовать кортеж как ключ в словаре или элемент множества.
Объявление:
point = (10, 20) date = (2025, 7, 15) pair = ("ключ", "значение")
Операции:
x, y = point # распаковка first = date[0] # доступ по индексу # point[0] = 11 # ошибка: кортеж неизменяем
Когда использовать:
- Данные фиксированы и не должны меняться: координаты, дата, пара значений.
- Нужно передать «пакет» значений, который не должен случайно измениться.
- Нужен ключ для словаря или элемент множества (только неизменяемые типы).
Пример: координаты точек на плоскости, которые не меняются:
points = [(0, 0), (1, 2), (3, 5)] for x, y in points: print(x, y)
Здесь каждый элемент списка — кортеж. Список хранит последовательность, кортежи гарантируют, что координаты не изменятся случайно.
Множества (set): когда важны уникальность и быстрые проверки
Множество — это неупорядоченная коллекция уникальных элементов. Порядок не гарантирован, дубликаты автоматически удаляются. Зато проверка «есть ли элемент» работает очень быстро.
Объявление:
unique_tags = {"python", "web", "data"} empty = set() # не {} — это пустой словарь
Операции:
unique_tags.add("ai") unique_tags.remove("web") has_ai = "ai" in unique_tags # True has_web = "web" in unique_tags # False
Математические операции:
a = {1, 2, 3} b = {3, 4, 5} union = a | b # {1, 2, 3, 4, 5} — объединение intersection = a & b # {3} — пересечение difference = a - b # {1, 2} — разность
Когда использовать:
- Нужны только уникальные значения, дубликаты не нужны.
- Часто проверяется наличие элемента: «уже видели этот ID?», «есть ли такой тег?».
- Нужны операции над коллекциями: объединение, пересечение, разность.
Пример: фильтрация повторяющихся email при импорте:
emails_raw = ["a@example.com", "b@example.com", "a@example.com"] emails_unique = set(emails_raw) # {'a@example.com', 'b@example.com'}
Словари (dict): когда нужно связывать ключи и значения
Словарь — это коллекция пар «ключ: значение». Ключи уникальны и должны быть неизменяемыми (строки, числа, кортежи). Порядок вставки сохраняется (начиная с Python 3.7+), но главный смысл словаря — быстрый поиск по ключу.
Объявление:
user = {"id": 101, "name": "Анна", "role": "admin"} prices = {"яблоко": 120, "банан": 80}
Операции:
role = user["role"] # "admin" user["email"] = "anna@example.com" # добавление del prices["банан"] # удаление # безопасный доступ city = user.get("city", "Москва") # если ключа нет — вернётся "Москва"
Когда использовать:
- Нужно быстро получать значение по ключу: пользователь по ID, цена по названию товара.
- Данные удобно описывать как пары «атрибут: значение»: профиль пользователя, настройки, метаданные.
- Нужна ассоциативная структура, а не просто список значений.
Пример: быстрый поиск цены по названию:
prices = {"яблоко": 120, "банан": 80, "апельсин": 95} name = "банан" if name in prices: print(prices[name]) else: print("Товар не найден")
Сравнительная таблица: что выбрать
| Структура | Порядок | Изменяемость | Уникальность | Быстрый поиск | Типичный сценарий |
|---|---|---|---|---|---|
list |
Да | Да | Нет | По индексу | Последовательность, которую меняют |
tuple |
Да | Нет | Нет | По индексу | Фиксированные пакеты данных |
set |
Нет | Да | Да (автоматически) | По наличию элемента | Уникальные значения, операции над множествами |
dict |
Да (с 3.7+) | Да (значения и пары) | Ключи уникальны | По ключу | Связывание ключей и значений |
Практические примеры выбора
Пример 1: список пользователей для отображения
Нужно показать пользователей в порядке регистрации и позволить удалять/добавлять:
users = [ {"id": 1, "name": "Анна"}, {"id": 2, "name": "Борис"}, ] users.append({"id": 3, "name": "Виктор"})
Здесь подходит список словарей: порядок важен, состав меняется.
Пример 2: набор разрешённых ролей
Роли не должны повторяться, и нужно быстро проверить, разрешена ли роль:
allowed_roles = {"admin", "editor", "viewer"} if current_role in allowed_roles: # доступ разрешён ...
Множество даёт уникальность и быстрый in.
Пример 3: фиксированные настройки конфигурации
Настройки не должны случайно меняться в коде:
config = ("production", 8080, True) env, port, debug = config
Кортеж защищает от случайных изменений и ясно показывает, что это неизменяемый набор.
Пример 4: быстрый поиск по ID
Есть много записей, нужен мгновенный доступ по ID:
by_id = { 101: {"name": "Анна", "role": "admin"}, 102: {"name": "Борис", "role": "user"}, } user = by_id.get(101)
Словарь даёт O(1) доступ по ключу, что критично при большом количестве записей.
Частые ошибки и как их избежать
- Использовать список там, где нужно множество. Если цель — уникальные значения и быстрый поиск, список будет работать медленнее и не гарантирует уникальность.
- Пытаться использовать список или словарь как ключ. Ключи должны быть неизменяемыми: подойдут строки, числа, кортежи. Списки и словари в качестве ключей использовать нельзя.
- Менять коллекцию во время перебора. Это может привести к пропуску элементов или ошибкам. Если нужно удалить элементы, лучше создать новую коллекцию или перебирать копию.
- Ожидать порядок в множестве. Порядок элементов в
setне определён. Если порядок важен — берите список или словарь.
Комбинации структур: как они работают вместе
Часто структуры используют вместе, чтобы получить нужные свойства.
Пример: хранение и быстрый поиск уникальных тегов:
tags_list = ["python", "web", "python", "data"] tags_set = set(tags_list) # уникальные теги tags_ordered = list(tags_set) # если нужен какой-то порядок # быстрый поиск if "web" in tags_set: ...
Пример: словарь со списком значений:
orders_by_user = { "anna": [101, 105, 110], "boris": [102, 108], }
Так можно хранить несколько заказов для каждого пользователя и быстро получать список по имени.
- Список — когда важен порядок и коллекция будет меняться.
- Кортеж — когда порядок важен, но данные фиксированы.
- Множество — когда нужны уникальные значения и быстрые проверки «есть/нет», а порядок не важен.
- Словарь — когда нужно связывать ключи и значения и быстро искать по ключу.
Выбор правильной структуры делает код понятнее и эффективнее: вы сразу видите, какие операции ожидаются (поиск, уникальность, изменение) и какие гарантии даёт структура (неизменяемость, порядок). Если сомневаетесь — начните с самого простого варианта (список или словарь), а затем при необходимости замените на более подходящую структуру.
