Перебор словарей в цикле
Все способы перебора словаря Python: ключи, значения, items(), фильтрация, включения и безопасное изменение словаря во время итерации.
Словари Python хранят данные в виде пар ключ-значение, и вам регулярно потребуется проходить по ним — для вывода каждой записи, фильтрации данных, преобразования значений или построения новых структур. В этой главе рассматриваются все стандартные способы итерации по словарю, объясняется, какой метод выбрать в каждой ситуации, и выделяется наиболее распространённая ошибка: изменение словаря во время его перебора.
Если вы только начинаете знакомиться со словарями, сначала прочитайте Словари Python. Для изучения общего синтаксиса циклов см. Циклы for в Python.
Перебор ключей
Если использовать обычный цикл for со словарём, Python по умолчанию будет итерировать по его ключам.
Перебор ключей словаря
person = {"name": "Alice", "age": 30, "city": "Berlin"}
for key in person:
print(key)Вывод:
name
age
cityВызов .keys() эквивалентен и делает намерение более явным:
Получив ключ, вы можете получить его значение внутри цикла:
person = {"name": "Alice", "age": 30, "city": "Berlin"}
for key in person:
print(key, "->", person[key])Вывод:
name -> Alice
age -> 30
city -> BerlinКогда использовать .keys()
Используйте форму for key in d, когда вам нужны только ключи. Явно указывайте d.keys(), когда хотите проверить принадлежность ("name" in d.keys()) или передать представление в другую функцию. Однако для простой проверки принадлежности if "name" in d работает быстрее.
Перебор значений
Используйте .values(), когда вам нужны только значения, а ключи не важны.
Перебор значений словаря
scores = {"math": 92, "science": 87, "english": 95}
for score in scores.values():
print(score)Вывод:
92
87
95Типичный вариант использования — вычисление итогового показателя по всем значениям:
scores = {"math": 92, "science": 87, "english": 95}
total = sum(scores.values())
average = total / len(scores)
print(f"Average score: {average:.1f}")Вывод:
Average score: 91.3Перебор пар ключ-значение с помощью .items()
.items() возвращает каждую запись в виде кортежа (key, value). Кортеж можно сразу распаковать в две переменные. Это наиболее универсальный способ итерации, к которому вы будете обращаться чаще всего.
Перебор пар ключ-значение
person = {"name": "Alice", "age": 30, "city": "Berlin"}
for key, value in person.items():
print(f"{key}: {value}")Вывод:
name: Alice
age: 30
city: BerlinФильтрация при переборе
Сочетайте цикл for с условием if, чтобы обрабатывать только нужные записи.
Вывод только товаров в наличии
inventory = {"apples": 5, "bananas": 0, "oranges": 3, "grapes": 0}
print("In stock:")
for item, qty in inventory.items():
if qty > 0:
print(f" {item}: {qty}")Вывод:
In stock:
apples: 5
oranges: 3Сортировка записей словаря
В Python 3.7+ словари гарантированно сохраняют порядок вставки. Если вам нужен другой порядок, отсортируйте ключи или записи перед перебором — сам словарь при этом не изменяется.
Сортировка по ключу (по алфавиту)
book = {"banana": 7, "apple": 3, "cherry": 12}
for fruit in sorted(book):
print(f"{fruit}: {book[fruit]}")Вывод:
apple: 3
banana: 7
cherry: 12Сортировка по значению
Передайте функцию key в sorted(), чтобы задать критерий сортировки.
book = {"banana": 7, "apple": 3, "cherry": 12}
for fruit, count in sorted(book.items(), key=lambda item: item[1], reverse=True):
print(f"{fruit}: {count}")Вывод:
cherry: 12
banana: 7
apple: 3Использование enumerate() при переборе
Оберните .items() в enumerate(), чтобы получать счётчик вместе с каждой парой ключ-значение.
colors = {"red": "#FF0000", "green": "#00FF00", "blue": "#0000FF"}
for index, (name, hex_code) in enumerate(colors.items()):
print(f"{index}: {name} -> {hex_code}")Вывод:
0: red -> #FF0000
1: green -> #00FF00
2: blue -> #0000FFВключения словарей
Включение словаря создаёт новый словарь из существующего в одном выражении. Синтаксис аналогичен включениям списков, но использует фигурные скобки и двоеточие между ключом и значением.
Применить скидку 10% к каждой цене
prices = {"apple": 1.20, "banana": 0.50, "orange": 0.80}
discounted = {item: round(price * 0.9, 2) for item, price in prices.items()}
print(discounted)Вывод:
{'apple': 1.08, 'banana': 0.45, 'orange': 0.72}Можно добавить условие фильтрации в конце:
Оставить только студентов с результатом 90 и выше
students = {
"Alice": {"grade": "A", "score": 95},
"Bob": {"grade": "B", "score": 82},
"Carol": {"grade": "A", "score": 91},
}
top_students = {name: info for name, info in students.items() if info["score"] >= 90}
print(top_students)Вывод:
{'Alice': {'grade': 'A', 'score': 95}, 'Carol': {'grade': 'A', 'score': 91}}Перебор вложенных словарей
Когда значения сами являются словарями (см. Вложенные словари), доступ к внутренним записям осуществляется через второй индекс или второй цикл.
Вывод всех полей для каждого студента
students = {
"Alice": {"grade": "A", "score": 95},
"Bob": {"grade": "B", "score": 82},
"Carol": {"grade": "A", "score": 91},
}
for name, info in students.items():
print(f"{name}: grade={info['grade']}, score={info['score']}")Вывод:
Alice: grade=A, score=95
Bob: grade=B, score=82
Carol: grade=A, score=91Изменение словаря во время перебора — главная ловушка
Вы не можете добавлять или удалять ключи из словаря во время его итерации. Python немедленно вызовет RuntimeError:
d = {"a": 1, "b": 2, "c": 3}
# This raises RuntimeError: dictionary changed size during iteration
for key in d:
if d[key] == 2:
del d[key]Безопасный способ — сначала собрать ключи, которые нужно удалить, а затем удалить их после завершения цикла:
Безопасное удаление после перебора
config = {"debug": True, "verbose": True, "timeout": 30}
keys_to_remove = [k for k, v in config.items() if v is True]
for k in keys_to_remove:
del config[k]
print(config)Вывод:
{'timeout': 30}Тот же принцип применяется к добавлению ключей: соберите новые пары, а затем обновите словарь с помощью update() или прямого присваивания после завершения цикла.
Выбор подходящего метода
| Задача | Метод |
|---|---|
| Итерация только по ключам | for key in d или for key in d.keys() |
| Итерация только по значениям | for value in d.values() |
| Итерация по ключам и значениям | for key, value in d.items() |
| Построение нового словаря | Включение словаря |
| Сортировка записей | sorted(d) или sorted(d.items(), key=...) |
| Индекс + пара ключ-значение | enumerate(d.items()) |
Полный набор операций со словарями см. в разделах Методы словарей Python и Копирование словарей.