Словари в Python

В этой статье мы разберем словари (dict) — один из самых мощных и гибких типов данных в Python.

Что такое словарь?

Словарь в Python — это коллекция пар "ключ-значение". Можно представить словарь как телефонную книгу, где имена людей (ключи) связаны с их номерами телефонов (значения).

Основные свойства словарей:

  • Ключи должны быть уникальными — нельзя иметь два одинаковых ключа в одном словаре
  • Ключи должны быть неизменяемыми — в качестве ключей можно использовать строки, числа, кортежи, но не списки или словари
  • Значения могут быть любого типа — числа, строки, списки, другие словари и т.д.
  • Начиная с Python 3.7, словари сохраняют порядок добавления элементов (раньше порядок не гарантировался)

Создание словарей

Существует несколько способов создать словарь в Python:

1. С помощью фигурных скобок

Python 3.13
# Пустой словарь
>>> empty_dict = {}

# Словарь с данными
>>> person = {"name": "John", "age": 30, "city": "New York"}
>>> print(person)
{'name': 'John', 'age': 30, 'city': 'New York'}
# Использование разных типов данных для ключей и значений >>> mixed = { ... "string": 100, # Строковый ключ ... 42: "number", # Числовой ключ ... (1, 2): "tuple", # Кортеж как ключ ... True: "boolean" # Логическое значение как ключ ... } ... print(mixed)
{'string': 100, 42: 'number', (1, 2): 'tuple', True: 'boolean'}
# Вложенные словари >>> nested = { ... "person": {"name": "Mary", "age": 25}, ... "contacts": {"email": "[email protected]", "phone": "+1234567890"} ... } ... print(nested["person"])
{'name': 'Mary', 'age': 25}

2. С помощью конструктора dict()

Python 3.13
# Пустой словарь
>>> empty_dict = dict()

# Из списка кортежей (пар ключ-значение)
>>> pairs = [("name", "Anna"), ("age", 28), ("city", "Berlin")]
>>> person = dict(pairs)
>>> print(person)
{'name': 'Anna', 'age': 28, 'city': 'Berlin'}
# С использованием именованных аргументов (только для строковых ключей) >>> settings = dict(theme="dark", font_size=12, notifications=True) >>> print(settings)
{'theme': 'dark', 'font_size': 12, 'notifications': True}

3. Генераторы словарей (dict comprehensions)

Python 3.13
# Словарь квадратов чисел (число: квадрат числа)
>>> squares = {x: x**2 for x in range(1, 6)}
>>> print(squares)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Фильтрация: только четные числа >>> even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0} >>> print(even_squares)
{2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

4. Метод fromkeys() для создания словаря с одинаковыми значениями

Python 3.13
# Создание словаря с заданными ключами и одинаковым значением для всех
>>> keys = ["name", "age", "city"]
>>> defaults = dict.fromkeys(keys, None)
>>> print(defaults)
{'name': None, 'age': None, 'city': None}
# Другой пример с значением по умолчанию >>> permissions = dict.fromkeys(["read", "write", "execute"], False) >>> print(permissions)
{'read': False, 'write': False, 'execute': False}

Доступ к элементам словаря

Доступ к значениям в словаре осуществляется через ключи:

Обращение по ключу

Python 3.13
>>> person = {"name": "John", "age": 30, "city": "New York"}

# Получение значения по ключу
>>> name = person["name"]
>>> print(name)
John
# Безопасный способ с помощью метода get() >>> phone = person.get("phone") # Вернет None, если ключа нет >>> print(phone)
None
# Метод get() с значением по умолчанию >>> phone = person.get("phone", "Not specified") >>> print(phone)
Not specified

Проверка наличия ключа

Python 3.13
>>> person = {"name": "John", "age": 30, "city": "New York"}

# Проверка наличия ключа
>>> print("name" in person)
True
>>> print("phone" not in person)
True

Доступ к вложенным словарям

Python 3.13
>>> nested = {
...     "person": {"name": "Mary", "age": 25},
...     "contacts": {"email": "[email protected]", "phone": "+1234567890"}
... }

# Доступ к значениям во вложенных словарях
>>> name = nested["person"]["name"]
>>> print(name)
Mary
# Безопасный доступ с помощью get() >>> email = nested.get("contacts", {}).get("email") >>> print(email)
mary@example.com
# Если путь не существует, вернется None или значение по умолчанию >>> website = nested.get("contacts", {}).get("website", "Not specified") >>> print(website)
Not specified

Изменение словарей

Словари в Python являются изменяемыми, поэтому их можно легко модифицировать:

Добавление и изменение элементов

Python 3.13
# Создаем словарь
>>> person = {"name": "John", "age": 30}

# Добавление нового ключа и значения
>>> person["city"] = "New York"
>>> print(person)
{'name': 'John', 'age': 30, 'city': 'New York'}
# Изменение значения существующего ключа >>> person["age"] = 31 >>> print(person)
{'name': 'John', 'age': 31, 'city': 'New York'}
# Использование метода update() для массового обновления >>> person.update({"age": 32, "job": "developer", "language": "Python"}) >>> print(person)
{'name': 'John', 'age': 32, 'city': 'New York', 'job': 'developer', 'language': 'Python'}

Удаление элементов

Python 3.13
>>> person = {"name": "John", "age": 30, "city": "New York", "job": "developer"}

# Удаление элемента по ключу с помощью del
>>> del person["job"]
>>> print(person)
{'name': 'John', 'age': 30, 'city': 'New York'}
# Удаление и возврат элемента с помощью pop() >>> age = person.pop("age") >>> print(age)
30
>>> print(person)
{'name': 'John', 'city': 'New York'}
# pop() с значением по умолчанию (не вызывает ошибку, если ключа нет) >>> job = person.pop("job", "Not specified") >>> print(job)
Not specified
# Удаление и возврат произвольного элемента с помощью popitem() # В Python 3.7+ возвращает последний добавленный элемент >>> item = person.popitem() >>> print(item)
('city', 'New York')
>>> print(person)
{'name': 'John'}
# Удаление всех элементов >>> person.clear() >>> print(person)
{}

Методы словарей

Python предоставляет множество полезных методов для работы со словарями:

Получение ключей, значений и пар ключ-значение

Python 3.13
>>> person = {"name": "John", "age": 30, "city": "New York"}

# Получение всех ключей
>>> keys = person.keys()
>>> print(keys)
dict_keys(['name', 'age', 'city'])
# Получение всех значений >>> values = person.values() >>> print(values)
dict_values(['John', 30, 'New York'])
# Получение всех пар ключ-значение >>> items = person.items() >>> print(items)
dict_items([('name', 'John'), ('age', 30), ('city', 'New York')])
# Объекты dict_keys, dict_values и dict_items являются представлениями словаря # Они динамически отражают изменения в словаре >>> person["job"] = "developer" >>> print(keys)
dict_keys(['name', 'age', 'city', 'job'])
# Преобразование представлений в списки >>> keys_list = list(keys) >>> print(keys_list)
['name', 'age', 'city', 'job']

Копирование словарей

Python 3.13
>>> original = {"name": "John", "age": 30, "settings": {"theme": "dark"}}

# Поверхностное копирование
>>> shallow_copy = original.copy()
>>> shallow_copy["name"] = "Peter"

>>> print(original["name"])
John
>>> print(shallow_copy["name"])
Peter
# Но вложенные объекты разделяются между копиями (поверхностное копирование) >>> shallow_copy["settings"]["theme"] = "light" >>> print(original["settings"]["theme"])
light
# Для глубокого копирования можно использовать модуль copy

Объединение словарей

Python 3.13
# Объединение словарей с update
>>> dict1 = {"a": 1, "b": 2}
>>> dict2 = {"b": 3, "c": 4}

# Создаем копию dict1 и обновляем её данными из dict2
>>> merged = dict1.copy()
>>> merged.update(dict2)
>>> print(merged)
{'a': 1, 'b': 3, 'c': 4}
# В Python 3.9+ можно использовать оператор | # merged = dict1 | dict2

Установка значения по умолчанию

Python 3.13
# Подсчет частоты слов
>>> counts = {}
>>> text = "one two one two three"
>>> words = text.split()

# Способ 1: проверка наличия ключа
>>> for word in words:
...     if word in counts:
...         counts[word] += 1
...     else:
...         counts[word] = 1
... print(counts)
{'one': 2, 'two': 2, 'three': 1}
# Способ 2: использование get() >>> counts = {} >>> for word in words: ... counts[word] = counts.get(word, 0) + 1 ... print(counts)
{'one': 2, 'two': 2, 'three': 1}

Итерация по словарям

Существует несколько способов перебора элементов словаря:

Python 3.13
>>> person = {"name": "John", "age": 30, "city": "New York"}

# Итерация по ключам (способ по умолчанию)
>>> print("Итерация по ключам:")
>>> for key in person:
...     print(key, ":", person[key])
Итерация по ключам:
name : John
age : 30
city : New York
# Итерация по значениям >>> print("Итерация по значениям:") >>> for value in person.values(): ... print(value)
Итерация по значениям:
John
30
New York
# Итерация по парам ключ-значение >>> print("Итерация по парам ключ-значение:") >>> for key, value in person.items(): ... print(key, ":", value)
Итерация по парам ключ-значение:
name : John
age : 30
city : New York

Вложенные структуры данных со словарями

Словари часто используются для создания сложных структур данных:

Python 3.13
# Список словарей (часто используется для данных из базы)
users = [
    {"id": 1, "name": "John", "email": "[email protected]"},
    {"id": 2, "name": "Mary", "email": "[email protected]"},
    {"id": 3, "name": "Alex", "email": "[email protected]"}
]

# Доступ к данным
for user in users:
    print(f"User: {user['name']}, Email: {user['email']}")

# Словарь словарей (для быстрого доступа по ключу)
users_by_id = {
    1: {"name": "John", "email": "[email protected]"},
    2: {"name": "Mary", "email": "[email protected]"},
    3: {"name": "Alex", "email": "[email protected]"}
}

# Быстрый доступ по ID
print(users_by_id[2]["name"])  # "Mary"

# Словарь списков (для группировки данных)
users_by_city = {
    "New York": ["John", "Alex"],
    "Berlin": ["Mary", "Elena"],
    "Paris": ["Dmitri"]
}

# Доступ к данным
for city, names in users_by_city.items():
    print(f"{city}: {', '.join(names)}")

Пример использования словаря

Python 3.13
>>> def count_frequency(items):
...     """Подсчет частоты элементов в последовательности."""
...     frequency = {}
...     for item in items:
...         frequency[item] = frequency.get(item, 0) + 1
...     return frequency

# Пример использования
>>> colors = ["red", "blue", "green", "blue", "red", "yellow", "red"]
>>> color_counts = count_frequency(colors)
>>> print(color_counts)
{'red': 3, 'blue': 2, 'green': 1, 'yellow': 1}

Распространенные ошибки при работе со словарями

  1. Обращение к несуществующему ключу

    Python 3.13
    >>> user = {"name": "John", "age": 30}
    
    # Небезопасно (может вызвать KeyError)
    >>> try:
    ...     print(user["email"])
    ... except KeyError as e:
    ...     print(f"Error: {e}")
    
    Error: 'email'
    # Правильно (безопасно) >>> print(user.get("email", "not specified"))
    not specified
  2. Проблемы с мутабельными ключами

    Python 3.13
    # Неправильно: список не может быть ключом
    >>> try:
    ...     invalid_dict = {[1, 2, 3]: "value"}
    ... except TypeError as e:
    ...     print(f"Error: {e}")
    
    Error: unhashable type: 'list'
    # Правильно: используйте неизменяемые типы для ключей >>> valid_dict = {(1, 2, 3): "value"} >>> print(valid_dict)
    {(1, 2, 3): 'value'}
  3. Неглубокое копирование

    Python 3.13
    >>> original = {"user": {"name": "John", "age": 30}}
    
    # Неправильно: неглубокое копирование
    >>> copy_dict = original.copy()
    >>> copy_dict["user"]["name"] = "Peter"
    >>> print(original["user"]["name"])
    
    Peter
    # Для глубокого копирования нужно использовать copy.deepcopy()

Проверка понимания

Какой из следующих способов безопасно получит значение по ключу из словаря, вернув альтернативное значение, если ключ отсутствует?


Мы с вами на связи
Русский