Словари в Python: как хранить и обрабатывать данные в виде ключей и значений
Пары «ключ - значение» в Python представлены структурой данных, называемой словарём (dict). Словарь хранит элементы, каждый из которых состоит из уникального ключа и связанного с ним значения. Поиск, добавление и удаление элементов выполняются быстро, так как внутренняя реализация основана на хэш-таблице. Словари широко применяются для представления сущностей, настройки конфигураций, кэширования и обработки данных.
Основное решение: словарь (dict)
Как создать словарь и работать с парами ключ-значение?
Самый распространённый способ - использование фигурных скобок {} с парами ключ: значение или встроенной функции dict(). Ключами могут быть только неизменяемые типы: строки, числа, кортежи (если содержат только неизменяемые элементы). Значения могут быть любыми объектами.
# Создание словаря
person = {'name': 'Иван', 'age': 30, 'city': 'Москва'}
print(person)
значения списка числа python (итерация по значениям списка чисел в python)
{'name': 'Иван', 'age': 30, 'city': 'Москва'}
словарь set python (словарь и set в python)
Доступ к значению осуществляется по ключу через квадратные скобки или метод get(). Метод get() безопаснее: при отсутствии ключа он возвращает None или значение по умолчанию, не вызывая исключения.
print(person['name']) # 'Иван'
print(person.get('salary', 0)) # 0
Python dict set (словарь и множество в python)
Изменение или добавление новой пары выполняется присваиванием:
person['salary'] = 100000
person['age'] = 31
print(person)
типы структур python (типы структур данных в python)
{'name': 'Иван', 'age': 31, 'city': 'Москва', 'salary': 100000}
вложенные структуры данных в python (вложенные структуры данных в python)
Удаление пары - оператор del или метод pop():
del person['city']
age = person.pop('age')
print(person, age)
кортеж чисел python (кортеж чисел в python)
{'name': 'Иван', 'salary': 100000} 31
язык программирования python массивы (массивы (списки) в python)
Возможные проблемы и ошибки:
- KeyError - при обращении к отсутствующему ключу через квадратные скобки. Решение: использовать
get()или проверять наличие черезin. - TypeError - попытка использовать изменяемый тип (список, другой словарь) в качестве ключа. Ключ должен быть хэшируемым.
- Порядок элементов в словаре гарантированно сохраняется начиная с Python 3.7, но полагаться на него не стоит, если нужна строгая упорядоченность.
Как автоматически задать значение по умолчанию для отсутствующего ключа?
Класс defaultdict из модуля collections позволяет указать фабричную функцию, вызываемую при обращении к несуществующему ключу. Это удобно для группировки, подсчёта и т.д.
from collections import defaultdict
words = ['apple', 'banana', 'apple', 'cherry', 'banana']
counts = defaultdict(int) # int() возвращает 0
for w in words:
counts[w] += 1
print(dict(counts))
массивы данных python 3 (массивы данных в python)
{'apple': 2, 'banana': 2, 'cherry': 1}
одномерные массивы на языке программирования python (одномерные массивы в python)
Ошибка:
Если забыть указать фабрику, defaultdict будет вызывать KeyError так же, как обычный словарь.
Как сохранить порядок добавления элементов в словаре?
OrderedDict из collections явно гарантирует порядок, даже в старых версиях Python. В современных версиях обычный dict тоже упорядочен, но OrderedDict предоставляет дополнительные методы, например move_to_end().
from collections import OrderedDict
ordered = OrderedDict([('a', 1), ('b', 2)])
ordered.move_to_end('a') # переместить 'a' в конец
print(ordered)
последовательности в python и способы их реализации (последовательности в python и способы их реализации)
OrderedDict([('b', 2), ('a', 1)])
программы с массивами на python (программы с массивами на python)
Как создать словарь с помощью генератора (dict comprehension)?
Для преобразования одной последовательности в словарь или фильтрации ключей применяется генератор словаря.
# Квадраты чисел от 0 до 4
squares = {x: x**2 for x in range(5)}
print(squares)
Python пар (пары (ключ-значение) в python)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Python разница списков (разница между списками и кортежами в python)
Если ключи повторяются, последнее значение перезапишет предыдущее - это не всегда очевидно.
Как объединить два словаря?
В Python 3.9+ появился оператор | для объединения словарей. В более старых версиях используют update() или распаковку {**d1, **d2}.
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
merged = d1 | d2 # значение 'b' будет из d2
print(merged)
как сделать массив python (создание массива (списка) в python)
{'a': 1, 'b': 3, 'c': 4}
списки в языке python (списки в python)
Как подсчитать количество вхождений элементов с помощью Counter?
Counter из collections - это подкласс словаря, автоматически подсчитывающий элементы.
from collections import Counter
colours = ['red', 'blue', 'red', 'green', 'blue', 'blue']
counts = Counter(colours)
print(counts)
print(counts.most_common(1)) # самый частый
упорядоченные структуры данных в python (упорядоченные структуры данных в python)
Counter({'blue': 3, 'red': 2, 'green': 1})
[('blue', 3)]
Расширенные примеры работы со словарями
Вложенные словари
Часто данные имеют иерархическую структуру. Словари могут быть значениями ключей.
users = {
'user1': {'name': 'Анна', 'age': 25, 'skills': ['Python', 'SQL']},
'user2': {'name': 'Петр', 'age': 30, 'skills': ['Java', 'C++']}
}
print(users['user1']['skills'][0])
Python
Сериализация словаря в JSON
Модуль json преобразует словарь в строку и обратно.
import json
data = {'name': 'Тест', 'value': 42}
json_str = json.dumps(data, ensure_ascii=False)
loaded = json.loads(json_str)
print(json_str)
print(loaded)
{"name": "Тест", "value": 42}
{'name': 'Тест', 'value': 42}
Использование словаря для кэширования результатов функции
Мемоизация ускоряет повторные вызовы с теми же аргументами.
fib_cache = {}
def fib(n):
if n in fib_cache:
return fib_cache[n]
if n < 2:
result = n
else:
result = fib(n-1) + fib(n-2)
fib_cache[n] = result
return result
print(fib(10))
print(fib_cache)
55
{0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55}
Фильтрация словаря по условию
Генератор словаря с условием.
ages = {'Иван': 30, 'Мария': 22, 'Пётр': 35, 'Анна': 18}
adults = {name: age for name, age in ages.items() if age >= 18}
print(adults)
{'Иван': 30, 'Мария': 22, 'Пётр': 35, 'Анна': 18}
Сортировка словаря по ключам или значениям
Словари сами по себе не сортируются, но можно получить отсортированный список пар.
d = {'z': 1, 'y': 2, 'a': 3}
sorted_by_key = dict(sorted(d.items()))
sorted_by_value = dict(sorted(d.items(), key=lambda item: item[1]))
print(sorted_by_key)
print(sorted_by_value)
{'a': 3, 'y': 2, 'z': 1}
{'z': 1, 'y': 2, 'a': 3}
Безопасное получение вложенных значений с помощью chains
Цепочка вызовов get() или библиотека dict-utils, но можно использовать pydash.
config = {
'database': {
'host': 'localhost',
'port': 5432
}
}
# Безопасное получение
port = config.get('database', {}).get('port', 5432)
print(port)
5432
Преобразование списка кортежей в словарь
Функция dict() принимает итератор из пар.
pairs = [('a', 1), ('b', 2), ('c', 3)]
d = dict(pairs)
print(d)
{'a': 1, 'b': 2, 'c': 3}
Использование setdefault для создания вложенных словарей
Метод setdefault возвращает значение ключа, а если его нет - создаёт новое.
from collections import defaultdict
# Автоматическое создание подсловарей
data = defaultdict(dict)
data['user1']['name'] = 'Алексей'
print(data)
defaultdict(<class 'dict'>, {'user1': {'name': 'Алексей'}})
Сравнение производительности: in vs get
Оба способа быстры, но in явно проверяет наличие, а get возвращает None или значение по умолчанию.
import timeit
d = {i: i for i in range(10000)}
def test_in():
return 9999 in d
def test_get():
return d.get(9999)
print(timeit.timeit(test_in, number=100000))
print(timeit.timeit(test_get, number=100000))
0.007... 0.008...
Результат может незначительно отличаться, но оба способа эффективны.