Python dict: полное руководство по словарям
Словарь dict: основные концепции
Словарь (dict) - это встроенный тип данных Python, предназначенный для хранения пар “ключ-значение”. Ключи обязаны быть неизменяемыми (хэшируемыми) объектами: числа, строки, кортежи. Значения могут быть любыми. Словари реализованы как хеш-таблицы, что обеспечивает быстрый доступ по ключу.
Как создать словарь и работать с ним базово?
Самый распространенный способ - литерал {} с перечислением пар через запятую.
student = {
"name": "Иван",
"group": "ПИ-21",
"grades": [5, 4, 5]
}Python dict (словарь dict в python)
Доступ к значениям - по ключу в квадратных скобках. Если ключа нет, возникает KeyError. Для безопасного доступа применяется dict.get(key, default).
print(student["name"]) # Иван
print(student.get("age", 0)) # 0 (ключа нет)
get() или блок try/except.Изменение и добавление элементов выполняется присваиванием:
student["group"] = "ПИ-22" # изменение
student["city"] = "Москва" # добавление
Удаление - оператор del или метод pop():
del student["grades"]
removed = student.pop("city", None)
Как создать словарь с помощью конструктора dict()?
Конструктор принимает различные источники данных: список кортежей, именованные аргументы, другой словарь.
# Из списка пар
pairs = [("x", 10), ("y", 20)]
d1 = dict(pairs) # {'x': 10, 'y': 20}
# Из именованных аргументов
d2 = dict(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3}
# Копирование
original = {"key": "value"}
copy_dict = dict(original) # поверхностная копия
copy.deepcopy().Как объединить несколько словарей?
Метод update() добавляет пары из другого словаря или итерируемого объекта, перезаписывая существующие ключи. В Python 3.9+ доступен оператор | для слияния.
base = {"a": 1, "b": 2}
extra = {"b": 3, "c": 4}
base.update(extra) # base стал {'a': 1, 'b': 3, 'c': 4}
# Слияние без изменения исходных
merged = {**base, **extra} # или base | extra (Python 3.9+)
Как получить все ключи, значения или пары?
Методы keys(), values(), items() возвращают представления (view), которые динамически отражают изменения словаря.
d = {"one": 1, "two": 2, "three": 3}
print(list(d.keys())) # ['one', 'two', 'three']
print(list(d.values())) # [1, 2, 3]
print(list(d.items())) # [('one', 1), ('two', 2), ('three', 3)]
Как проверить наличие ключа или значения?
Оператор in проверяет наличие ключа. Для проверки значения - in по values().
if "one" in d:
print("Ключ есть")
if 1 in d.values():
print("Значение есть")
Как удалить все элементы или конкретный?
Метод clear() очищает словарь. pop(key, default) удаляет ключ и возвращает значение или default, если ключа нет. popitem() удаляет и возвращает последнюю добавленную пару (в Python 3.7+).
d.clear()
print(d) # {}
d = {"x": 10, "y": 20}
val = d.pop("x", None) # val = 10, d = {"y": 20}
last = d.popitem() # ('y', 20), d = {}
Как использовать setdefault для задания значения по умолчанию?
Метод setdefault(key, default) возвращает значение по ключу, если ключ существует, иначе вставляет default и возвращает его. Удобно для подсчета или группировки.
counts = {}
word = "apple"
counts[word] = counts.get(word, 0) + 1
# Альтернатива с setdefault:
counts.setdefault(word, 0)
counts[word] += 1
Типичные проблемы и их решения
- KeyError при обращении к отсутствующему ключу. Применяется
get()илиsetdefault(). - TypeError: unhashable type при попытке использовать изменяемый объект (список, словарь) в качестве ключа. Преобразование в кортеж или строку.
- Изменение словаря во время итерации. Нельзя добавлять или удалять элементы при переборе циклом
for k in d:. Создается копия ключей:for k in list(d.keys()):. - Порядок элементов. В Python 3.7+ словари сохраняют порядок вставки. В более старых версиях порядок не гарантирован. Для упорядоченного словаря применяется
OrderedDictиз модуляcollections.
Продвинутые примеры и нестандартные приёмы
defaultdict для автоматической инициализации
from collections import defaultdict
word_counts = defaultdict(int)
words = ["a", "b", "a", "c", "b", "b"]
for w in words:
word_counts[w] += 1
print(dict(word_counts))
{'a': 2, 'b': 3, 'c': 1}
Counter для подсчета элементов
from collections import Counter
letters = Counter("abracadabra")
print(letters)
print(letters.most_common(2))
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
[('a', 5), ('b', 2)]
Dict comprehension с условием
numbers = [1, 2, 3, 4, 5]
# Словарь квадратов только для четных чисел
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(even_squares)
{2: 4, 4: 16}
Объединение словарей оператором | и |=
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
# Новый словарь
merged = d1 | d2
print(merged)
# Изменение существующего (Python 3.9+)
d1 |= d2
print(d1)
{'a': 1, 'b': 3, 'c': 4}
{'a': 1, 'b': 3, 'c': 4}
Безопасный доступ к вложенным словарям
data = {"user": {"name": "Alice", "address": {"city": "Moscow"}}}
# Обычный доступ с риском KeyError
# city = data["user"]["address"]["city"]
# Безопасный через цепочку get
city = data.get("user", {}).get("address", {}).get("city", None)
print(city)
Moscow
Сортировка словаря по значениям
scores = {"Alice": 90, "Bob": 85, "Charlie": 95}
# Сортировка по значениям (по возрастанию)
sorted_items = sorted(scores.items(), key=lambda x: x[1])
print(dict(sorted_items))
# По убыванию
sorted_desc = sorted(scores.items(), key=lambda x: x[1], reverse=True)
print(dict(sorted_desc))
{'Bob': 85, 'Alice': 90, 'Charlie': 95}
{'Charlie': 95, 'Alice': 90, 'Bob': 85}
Мемоизация (кэширование) с помощью словаря
def factorial(n, cache={}):
if n in cache:
return cache[n]
if n <= 1:
return 1
cache[n] = n * factorial(n-1)
return cache[n]
print(factorial(10))
3628800
Преобразование двух списков в словарь
keys = ["name", "age", "city"]
values = ["Alice", 30, "Moscow"]
d = dict(zip(keys, values))
print(d)
{'name': 'Alice', 'age': 30, 'city': 'Moscow'}
Инверсия словаря (значения становятся ключами)
original = {"a": 1, "b": 2, "c": 3}
# При условии уникальности значений
inverted = {v: k for k, v in original.items()}
print(inverted)
# Если значения могут повторяться, использовать списки
original2 = {"a": 1, "b": 2, "c": 1}
from collections import defaultdict
inv_default = defaultdict(list)
for k, v in original2.items():
inv_default[v].append(k)
print(dict(inv_default))
{1: 'a', 2: 'b', 3: 'c'}
{1: ['a', 'c'], 2: ['b']}