Словари, множества и comprehensions
Тема дорожной карты · Python Programming
Comprehension создаёт новый list, set или dict из итерируемого одним выражением: [f(x) for x in xs if cond(x)]. Читается сверху вниз как обычный цикл и обычно работает быстрее. Не вкладывай больше двух for — теряется читаемость; лучше обычный цикл или генераторное выражение. Генераторы ((...) вместо [...]) выдают элементы лениво и идеальны для больших данных, которые передаются в sum, any, min и т. п.
Как это работает
Словари, множества и comprehensions покрывает четыре встроенных контейнера (list, tuple, set, dict) плюс модуль collections (Counter, defaultdict, deque, namedtuple, OrderedDict). Списки — изменяемые упорядоченные последовательности с O(1) append; кортежи — неизменяемые; множества — на хешах с O(1) проверкой членства; словари — хеш-таблицы с гарантированным порядком вставки с Python 3.7. Comprehensions ([x*2 for x in xs]) создают эти контейнеры в одном выражении и обычно быстрее явных циклов.
Когда применять
Выбор контейнера диктует паттерн доступа: list — упорядоченный доступ по индексу, tuple — fixed-size записи или ключи словаря, set — членство/дедуп, dict — поиск по ключу. Comprehensions — когда трансформация очевидна (читаемый one-liner); generator expressions — когда данных много и их можно стримить. Берите collections.Counter для подсчёта частот, defaultdict чтобы избежать setdefault-бойлерплейта, deque для FIFO/LIFO с O(1) на обоих концах.
Типичные ошибки
Ловушки Словари, множества и comprehensions: копирование вложенных списков через = (получаете ссылку, не копию — нужен copy.deepcopy); использование изменяемых объектов как ключей словаря (TypeError); итерация + мутация списка одновременно (размер меняется в цикле = пропуски); выбор list-of-tuples вместо dict — и O(1) превращается в O(n). Профилируйте через timeit, прежде чем считать comprehension быстрее — иногда явный цикл с .append выигрывает в ясности.