📜 Ручная группировка через обычные словари
Можно обойтись без defaultdict, но код становится длиннее из-за постоянных проверок ключей:
# manual_grouping.py
sales = [
{"date": "2025-02-01", "amount": 100, "category": "Electronics"},
{"date": "2025-02-02", "amount": 200, "category": "Electronics"},
]
grouped = {}
for record in sales:
key = (record["date"][:4], record["date"][5:7], record["category"])
if key not in grouped:
grouped[key] = []
grouped[key].append(record)
# Для сумм приходится делать двойную проверку
category_totals = {}
for record in sales:
period = (record["date"][:4], record["date"][5:7])
if period not in category_totals:
category_totals[period] = {}
if record["category"] not in category_totals[period]:
category_totals[period][record["category"]] = 0
category_totals[period][record["category"]] += record["amount"]
Этот код работает, но содержит много шаблонных проверок.
✅ Группировка через defaultdict
С defaultdict проверки исчезают — фабрика значений создаёт нужные структуры автоматически:
# defaultdict_grouping.py
from collections import defaultdict
sales = [
{"date": "2025-02-01", "amount": 100, "category": "Electronics"},
{"date": "2025-02-02", "amount": 200, "category": "Electronics"},
]
grouped = defaultdict(list)
category_totals = defaultdict(lambda: defaultdict(int))
for record in sales:
key = (record["date"][:4], record["date"][5:7], record["category"])
grouped[key].append(record)
category_totals[(record["date"][:4], record["date"][5:7])][record["category"]] += record["amount"]
- Меньше кода и меньше ошибок.
- Легче читать и поддерживать.
- Не нужно помнить об инициализации каждого уровня вложенности.
📜 Разбор строк через split(",")
В исходном задании строки разбираются через split(","). Это простой и понятный способ, если формат гарантированно простой:
# split_approach.py
line = "Olivia Suarez,2024-08-02,4565,Electronics,Dallas"
parts = line.strip().split(",")
name, date, amount, category, city = parts
Проблемы появляются, если в данных встречаются запятые внутри полей или кавычки. В таких случаях split даст неверный результат.
✅ Разбор через модуль csv
Модуль csv корректно обрабатывает кавычки, запятые внутри полей и экранирование:
# csv_approach.py
import csv
with open("sales_data.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
for row in reader:
name, date, amount, category, city = row
csv не разбирается в исходной лекции, но является рекомендуемым инструментом для работы с настоящими CSV-файлами.
📜 Ручное склеивание путей
Начинающие иногда пишут пути вручную, что ломается при переносе на другую ОС:
# Неправильно
path = output_dir + "\\" + year + "\\" + month + "\\" + filename
✅ Кроссплатформенные пути через os.path.join
# Правильно
import os
path = os.path.join(output_dir, year, month, filename)
Этот код работает одинаково на Windows, Linux и macOS.
🕰️ Когда какой подход использовать
| Ситуация | Рекомендуемый подход |
|---|---|
| Учебный файл с гарантированно простым форматом | split(",") + defaultdict |
| Реальные CSV-файлы из внешних источников | Модуль csv |
| Нужна группировка по нескольким уровням | defaultdict или collections.Counter |
| Работа с путями в любом проекте | os.path.join или pathlib.Path |
pathlib — современная объектно-ориентированная альтернатива os.path, не разбираемая в исходной лекции.