Перейти до основного вмісту
Модуль 8 · Урок 3 із 431/36 у курсі~12 min
Модульні уроки (3/4)

колекції: лічильник і defaultdict

Модуль collections додає спеціальні типи даних, які розширюють вбудовані колекції. Три найбільш використовувані: Counter, defaultdict, namedtuple.

Counter: підрахунок частоти

Python
from collections import Counter

parole = ["mela", "pera", "mela", "kiwi", "mela", "pera"]
c = Counter(parole)
# Counter({'mela': 3, 'pera': 2, 'kiwi': 1})

c["mela"]            # 3
c["banana"]          # 0   (default for missing keys, NO KeyError)
c.most_common(2)     # [('mela', 3), ('pera', 2)]

Він також працює з рядками (підраховує символи):

Python
Counter("ciao mondo")
# Counter({'o': 2, 'c': 1, 'i': 1, 'a': 1, ' ': 1, 'm': 1, 'n': 1, 'd': 1})

Він підтримує операції, подібні до множин, над підрахунками (+, -, &, |) — дуже зручно для агрегування підрахунків із різних джерел.

defaultdict: dict з автоматичним замовчуванням

Dict, який, коли ви отримуєте доступ до відсутнього ключа, створює його, викликаючи a фабрика.

Python
from collections import defaultdict

gruppi = defaultdict(list)        # factory = list (empty list)
for nome in ["Ada", "Linus", "Ada", "Grace"]:
    gruppi[nome].append(1)
# defaultdict(list, {'Ada': [1, 1], 'Linus': [1], 'Grace': [1]})

Без defaultdict вам довелося б написати:

Python
gruppi = {}
for nome in [...]:
    if nome not in gruppi:
        gruppi[nome] = []
    gruppi[nome].append(1)

Загальні фабрики: list, int (за замовчуванням 0), set, dict.

namedtuple: кортежі з іменами полів

Легкий спосіб створення незмінних класів записів. Це кортеж, але з доступом до поля за назвою.

Python
from collections import namedtuple

Punto = namedtuple("Punto", ["x", "y"])
p = Punto(3, 4)
p.x          # 3 (access by name)
p[0]         # 3 (access by index, still a tuple)
p.x + p.y    # 7

# typical use: return multiple values from a function
def divisione(a, b):
    Risultato = namedtuple("Risultato", ["quoziente", "resto"])
    return Risultato(a // b, a % b)

r = divisione(17, 5)
r.quoziente   # 3
r.resto       # 2

(Для більш складних випадків існує також dataclasses з 3.7 — див. M9.)

namedtuple: легкі незмінні записи

Модуль collections також експортує namedtuple, який дозволяє швидко створювати легкі класоподібні об’єкти для зберігання структурованих даних без написання конструкторів або шаблонних методів:

Python
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)

Спробуйте

вправи#python.m8.l3.e1
Спроби: 0Завантаження…

З огляду на список `words = ['mela', 'pera', 'mela', 'kiwi', 'mela', 'pera']`, обчислити найбільш часто зустрічається слово в `top` як рядок. Оцініть `top`.

Завантаження редактора…
Показати підказку

Counter(...).most_common(1) повертає [(слово, кількість)].

Рішення доступне після 3 спроб

Повторна вправа

вправи#python.m8.l3.e2
Спроби: 0Завантаження…

Враховуючи студентів `enrollments = [('Ada', 'mate'), ('Linus', 'fisica'), ('Ada', 'storia'), ('Grace', 'mate')]`, створіть `courses_per_student` як defaultdict(list). Оцініть `dict(courses_per_student)`.

Завантаження редактора…
Показати підказку

defaultdict(list), а потім для s, c у записах.

Рішення доступне після 3 спроб

Додатковий виклик

вправи#python.m8.l3.e3
Спроби: 0Завантаження…

Імпортувати \`Лічильник\` із \`колекцій\`. Підрахуйте частоту символів у рядку \`text = "abracadabra"\`. Збережіть лічильник у \`char_counter\` і обчисліть його.

Завантаження редактора…
Показати підказку

Лічильник приймає рядок як параметр і підраховує повторення кожної літери.

Рішення доступне після 3 спроб