Словарь со списками внутри
Как складывать значения по ключу, когда ключа ещё нет.
Задача
Разложить записи по группам: ключ — группа, значение — список попавших в неё.
Прямолинейно это пишут так:
itog = {}
for imya, gruppa in zapisi:
if gruppa not in itog:
itog[gruppa] = []
itog[gruppa].append(imya)
Работает, и ничего дурного в этом нет. Но проверка «а есть ли уже такой ключ» повторяется в каждой такой задаче, и её убрали в метод.
setdefault
itog = {}
for imya, gruppa in zapisi:
itog.setdefault(gruppa, []).append(imya)
setdefault(klyuch, zapasnoe) возвращает значение по ключу, а если
ключа нет — сначала кладёт туда запасное и возвращает его. То есть
«достань список, а если его нет — заведи пустой».
defaultdict
Если группировка идёт по всему коду, удобнее объявить словарь, который сам создаёт пустые списки:
from collections import defaultdict
itog = defaultdict(list)
for imya, gruppa in zapisi:
itog[gruppa].append(imya)
У него есть особенность, о которой надо знать: обращение к несуществующему ключу создаёт его.
itog["нет такой группы"] # вернёт [] и заведёт эту группу
len(itog) # на одну больше, чем было
Поэтому для чтения такой словарь лучше превратить обратно:
dict(itog).
Подсчёт вместо списка
Та же конструкция считает количества:
schet = {}
for slovo in slova:
schet[slovo] = schet.get(slovo, 0) + 1
И для этого тоже есть готовое:
from collections import Counter
schet = Counter(slova)
Counter — это ровно такой цикл внутри. Написать его руками стоит
хотя бы раз: понимать, что там, полезнее, чем помнить название.