Работа со словарями Python 3: готовая шпаргалка с примерами

Словарь Python хранит пары «ключ – значение». В этой шпаргалке вы найдете готовые примеры для создания, изменения, удаления, перебора, фильтрации и сортировки dict. Каждый листинг запускается отдельно на Python 3.10+ и показывает ожидаемый вывод.

Словарь в Python 3: что это и как устроен

Словарь python 3 связывает уникальные ключи со значениями. Значением может быть строка, число, список или другой словарь.

Ключ должен быть хешируемым. Строки, числа и кортежи подходят, если элементы кортежа тоже хешируемы. Список и обычный словарь ключом быть не могут.

product = {'name': 'Клавиатура', 'price': 3500, 'tags': ['usb', 'black']}
print(product['name'])
print(product['tags'])
print(list(product))

Вывод:

Клавиатура
['usb', 'black']
['name', 'price', 'tags']

Python сохраняет порядок вставки словаря с версии 3.7. Новый ключ появляется в конце, но порядок вставки не заменяет сортировку.

Как создать словарь в Python

Способ зависит от исходных данных. Литерал подходит для ручного заполнения, zip() связывает две последовательности, а генератор словаря преобразует элементы.

keys = ['name', 'age', 'city']
values = ['Анна', 28, 'Казань']

empty = {}
manual = {'name': 'Анна', 'age': 28}
from_constructor = dict(name='Анна', age=28)
from_zip = dict(zip(keys, values))
from_keys = dict.fromkeys(['draft', 'published'], 0)
squares = {number: number * number for number in range(1, 4)}

print(empty)
print(manual)
print(from_constructor)
print(from_zip)
print(from_keys)
print(squares)

Вывод:

{}
{'name': 'Анна', 'age': 28}
{'name': 'Анна', 'age': 28}
{'name': 'Анна', 'age': 28, 'city': 'Казань'}
{'draft': 0, 'published': 0}
{1: 1, 2: 4, 3: 9}

dict.fromkeys() передает один объект всем ключам. Изменяемый список поэтому окажется общим для всех пар.

bad = dict.fromkeys(['a', 'b'], [])
bad['a'].append(1)
good = {key: [] for key in ['a', 'b']}
good['a'].append(1)
print(bad)
print(good)

Вывод:

{'a': [1], 'b': [1]}
{'a': [1], 'b': []}

Синтаксис типа dict описан в официальной документации Python. Интерпретатор можно скачать на сайте Python.

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

Выражение d[key] подходит для обязательного ключа. Метод get() возвращает запасное значение, а оператор in проверяет наличие ключа.

prices = {'book': 900, 'pen': 70}
print(prices['book'])
print(prices.get('notebook', 0))
print('pen' in prices)
print(prices.get('eraser'))

Вывод:

900
0
True
None

Квадратные скобки вызывают KeyError при отсутствии ключа. Без второго аргумента get() возвращает None.

Python добавить в словарь: новые и вложенные элементы

Чтобы python добавить элемент в словарь, присвойте значение по новому ключу. Такая запись также обновляет существующую пару.

user = {'name': 'Олег', 'age': 30}
user['city'] = 'Самара'
user['age'] = 31
user.update({'role': 'editor', 'active': True})
user.setdefault('visits', 0)
user.setdefault('age', 99)
print(user)

Вывод:

{'name': 'Олег', 'age': 31, 'city': 'Самара', 'role': 'editor', 'active': True, 'visits': 0}

Оператор |= обновляет левый словарь. Операторы объединения появились в Python 3.9.

settings = {'theme': 'light', 'font': 14}
settings |= {'theme': 'dark', 'language': 'ru'}
print(settings)

Вывод:

{'theme': 'dark', 'font': 14, 'language': 'ru'}

Добавление элементов в словарь python во вложенный словарь выполняется через цепочку ключей. setdefault() создает вложенный объект при первом обращении.

orders = {'order-1': {'status': 'new'}}
orders['order-1']['items'] = 2
orders.setdefault('order-2', {})['status'] = 'paid'
print(orders)

Вывод:

{'order-1': {'status': 'new', 'items': 2}, 'order-2': {'status': 'paid'}}

Удаление элементов из словаря

Выбирайте операцию по результату. del удаляет пару без возврата, pop() возвращает значение, popitem() забирает последнюю пару, а clear() очищает объект.

data = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
del data['a']
removed = data.pop('b', 0)
pair = data.popitem()
print(data)
print(removed)
print(pair)
data.clear()
print(data)

Вывод:

{'c': 30}
20
('d', 40)
{}

pop(key, default) не вызывает ошибку при отсутствии ключа. У del значения по умолчанию нет, поэтому отсутствие проверяйте через in.

Python перебор словаря: ключи, значения и пары

Цикл for key in d перебирает ключи. Методы keys(), values() и items() дают доступ к нужной части словаря.

scores = {'Аня': 5, 'Борис': 4, 'Вера': 5}
for key in scores.keys():
    print(key)
for value in scores.values():
    print(value)
for key, value in scores.items():
    print(key, value)

Вывод:

Аня
Борис
Вера
5
4
5
Аня 5
Борис 4
Вера 5

Размер словаря нельзя менять во время цикла: Python поднимет RuntimeError. Скопируйте ключи в список, если планируете удалять пары.

stock = {'pen': 4, 'book': 0, 'bag': 2}
for key in list(stock):
    if stock[key] == 0:
        del stock[key]
print(stock)

Вывод:

{'pen': 4, 'bag': 2}

Фильтрация словаря по ключу и значению

Генератор словаря создает новый объект и оставляет пары, для которых условие дает True. Условие можно применить к ключу, значению или обоим полям.

products = {'book': 900, 'pen': 70, 'lamp': 2400, 'bag': 1800}
by_price = {name: price for name, price in products.items() if price >= 1000}
by_name = {name: price for name, price in products.items() if name.startswith('b')}
combined = {name: price for name, price in products.items() if name.startswith('b') and price > 1000}
print(by_price)
print(by_name)
print(combined)

Вывод:

{'lamp': 2400, 'bag': 1800}
{'book': 900, 'bag': 1800}
{'bag': 1800}

Исходный словарь сохраняется. Для удаления на месте перебирайте list(d), а не живое представление ключей.

Сортировка словаря python по ключу и значению

Функция sorted() возвращает список. Передайте отсортированные пары в dict(), чтобы собрать словарь в новом порядке.

scores = {'Вера': 82, 'Анна': 95, 'Борис': 74, 'Глеб': 88}
by_key = dict(sorted(scores.items()))
by_value = dict(sorted(scores.items(), key=lambda item: item[1]))
by_value_desc = dict(sorted(scores.items(), key=lambda item: item[1], reverse=True))
print(by_key)
print(by_value)
print(by_value_desc)

Вывод:

{'Анна': 95, 'Борис': 74, 'Вера': 82, 'Глеб': 88}
{'Борис': 74, 'Вера': 82, 'Глеб': 88, 'Анна': 95}
{'Анна': 95, 'Глеб': 88, 'Вера': 82, 'Борис': 74}

Сортировка словаря по значению python использует второй элемент пары. Вместо lambda подойдет operator.itemgetter(1).

from operator import itemgetter
scores = {'Вера': 82, 'Анна': 95, 'Борис': 74, 'Глеб': 88}
result = dict(sorted(scores.items(), key=itemgetter(1), reverse=True))
print(result)

Вывод:

{'Анна': 95, 'Глеб': 88, 'Вера': 82, 'Борис': 74}

Для топ-N не собирайте полный порядок, если нужен только список лучших пар.

import heapq
scores = {'Вера': 82, 'Анна': 95, 'Борис': 74, 'Глеб': 88}
top_two = heapq.nlargest(2, scores.items(), key=lambda item: item[1])
print(top_two)

Вывод:

[('Анна', 95), ('Глеб', 88)]

Для обычной сортировки OrderedDict больше не нужен: встроенный словарь сохраняет порядок вставки. Этот класс полезен для move_to_end() и сравнения с учетом порядка.

from collections import OrderedDict
cache = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
cache.move_to_end('a')
print(list(cache.items()))

Вывод:

[('b', 2), ('c', 3), ('a', 1)]

defaultdict python 3 и Counter

defaultdict вызывает фабрику при обращении к отсутствующему ключу через квадратные скобки. Метод get() фабрику не запускает.

from collections import defaultdict, Counter
words = ['cat', 'dog', 'cat', 'bird', 'dog', 'cat']
frequencies = defaultdict(int)
for word in words:
    frequencies[word] += 1
groups = defaultdict(list)
for city, name in [('Казань', 'Анна'), ('Москва', 'Борис'), ('Казань', 'Вера')]:
    groups[city].append(name)
counter = Counter(words)
print(dict(frequencies))
print(dict(groups))
print(counter.most_common(2))

Вывод:

{'cat': 3, 'dog': 2, 'bird': 1}
{'Казань': ['Анна', 'Вера'], 'Москва': ['Борис']}
[('cat', 3), ('dog', 2)]

setdefault() удобен для разовой группировки: d.setdefault(key, []).append(value). В цикле defaultdict(list) яснее показывает автоматическое создание списка.

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

Оператор | создает новый словарь. Оператор |= и метод update() меняют левый объект. При совпадении ключей правое значение заменяет левое.

left = {'a': 1, 'shared': 'left'}
right = {'b': 2, 'shared': 'right'}
merged = left | right
copy_merge = {**left, **right}
left.update(right)
print(merged)
print(copy_merge)
print(left)

Вывод:

{'a': 1, 'shared': 'right', 'b': 2}
{'a': 1, 'shared': 'right', 'b': 2}
{'a': 1, 'shared': 'right', 'b': 2}

| сохраняет исходные словари. Берите update(), если изменение первого объекта допустимо.

Словари и pandas DataFrame

Словарь подходит для связи «ключ – значение». pandas DataFrame удобен для строк, столбцов, фильтрации и группировки. Установите библиотеку командой python -m pip install pandas.

import pandas as pd
by_columns = {'name': ['Анна', 'Борис'], 'score': [95, 82]}
df = pd.DataFrame.from_dict(by_columns, orient='columns')
print(df.to_string(index=False))
by_index = {'first': {'name': 'Анна', 'score': 95}, 'second': {'name': 'Борис', 'score': 82}}
indexed = pd.DataFrame.from_dict(by_index, orient='index')
print(indexed.to_string())

Вывод:

 name  score
 Анна     95
Борис     82
        name  score
first   Анна     95
second Борис     82

При orient='index' параметр columns выбирает столбцы и их порядок.

import pandas as pd
data = {
    'first': {'name': 'Анна', 'score': 95, 'city': 'Казань'},
    'second': {'name': 'Борис', 'score': 82, 'city': 'Москва'}
}
df = pd.DataFrame.from_dict(data, orient='index', columns=['name', 'score'])
print(df.to_string())

Вывод:

        name  score
first   Анна     95
second Борис     82

Метод to_dict() переводит DataFrame в разные формы: records дает список строк, list – столбцы со списками, index – строки по индексам.

import pandas as pd
df = pd.DataFrame({'name': ['Анна', 'Борис'], 'score': [95, 82]})
print(df.to_dict(orient='records'))
print(df.to_dict(orient='list'))
print(df.to_dict(orient='index'))

Вывод:

[{'name': 'Анна', 'score': 95}, {'name': 'Борис', 'score': 82}]
{'name': ['Анна', 'Борис'], 'score': [95, 82]}
{0: {'name': 'Анна', 'score': 95}, 1: {'name': 'Борис', 'score': 82}}

Список хранит последовательность, словарь связывает ключ с объектом, а массив NumPy рассчитан на однородные числовые данные. DataFrame выбирайте для табличных операций, а dict – для прямого доступа по ключу.

Ошибки при работе со словарями

Проверьте четыре типичные ситуации: отсутствующий ключ, нехешируемый ключ, изменение размера во время перебора и общий список из fromkeys().

data = {'a': 1}
try:
    print(data['b'])
except KeyError:
    print('Ключ отсутствует')
try:
    data[['list']] = 2
except TypeError:
    print('Список нельзя использовать как ключ')
stock = {'pen': 1, 'book': 0}
try:
    for key in stock:
        if stock[key] == 0:
            del stock[key]
except RuntimeError:
    print('Размер словаря нельзя менять во время перебора')
bad = dict.fromkeys(['x', 'y'], [])
bad['x'].append('shared')
print(bad)

Вывод:

Ключ отсутствует
Список нельзя использовать как ключ
Размер словаря нельзя менять во время перебора
{'x': ['shared'], 'y': ['shared']}

Для отсутствующего ключа используйте get() или in. Для удаления во время цикла создайте список ключей. Для независимых списков применяйте генератор словаря.

Таблица методов dict

Выбирайте метод по результату: одни операции читают данные, другие меняют словарь на месте.

Метод или операцияЧто делаетЧто возвращаетПример
get(key, default)Читает значение без ошибкиЗначение или defaultd.get('x', 0)
keys()Возвращает представление ключейdict_keysd.keys()
values()Возвращает представление значенийdict_valuesd.values()
items()Возвращает парыdict_itemsd.items()
update(other)Добавляет или заменяет парыNoned.update({'x': 1})
setdefault(key, value)Добавляет ключ при отсутствииЗначение ключаd.setdefault('x', 0)
pop(key, default)Удаляет ключУдаленное значениеd.pop('x', 0)
popitem()Удаляет последнюю паруКортеж из парыd.popitem()
clear()Очищает словарьNoned.clear()
dict.fromkeys(keys, value)Создает словарь из ключейНовый dictdict.fromkeys(['a', 'b'], 0)
d | otherОбъединяет словариНовый dictmerged = a | b
d |= otherОбновляет левый словарьНичего: словарь меняется на местеd |= other

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев