← Назад к вопросам
Что такое инструменты функционального программирования в collections?
2.0 Middle🔥 141 комментариев
#Python Core#Soft Skills
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Инструменты функционального программирования в collections
collections — это модуль Python, который предоставляет специализированные контейнеры данных, а также взаимодействует с функциональным подходом к программированию через итерирование, трансформацию и комбинирование коллекций. Хотя инструменты функционального программирования (map, filter, reduce) находятся в других модулях, collections тесно интегрируется с функциональным стилем.
Основные типы данных в collections
from collections import (
namedtuple, # Неизменяемые кортежи с именованными полями
defaultdict, # Словарь с дефолтными значениями
Counter, # Счётчик элементов
deque, # Двусторонняя очередь
OrderedDict # Упорядоченный словарь (Python 3.7+ встроен)
)
1. namedtuple
from collections import namedtuple
from functools import reduce
# Создать именованный кортеж
Point = namedtuple('Point', ['x', 'y'])
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = Point(5, 6)
print(p1.x, p1.y) # 1 2
print(p1[0]) # 1 (доступ как к кортежу)
# Функциональный подход: применить функцию к каждому point
points = [p1, p2, p3]
# Map: преобразовать в расстояния
def distance_from_origin(point):
return (point.x ** 2 + point.y ** 2) ** 0.5
distances = list(map(distance_from_origin, points))
print(distances) # [2.236..., 5.0, 7.810...]
# Filter: оставить точки с x > 2
filtered = list(filter(lambda p: p.x > 2, points))
print(filtered) # [Point(x=3, y=4), Point(x=5, y=6)]
# Reduce: найти сумму всех координат
total_sum = reduce(lambda acc, p: acc + p.x + p.y, points, 0)
print(total_sum) # 21
2. defaultdict с функциональным подходом
from collections import defaultdict
from functools import reduce
# Группировка данных функционально
students = [
('Alice', 'Math'),
('Bob', 'Math'),
('Charlie', 'English'),
('David', 'English'),
('Eve', 'Math')
]
# Способ 1: defaultdict с list
groups = defaultdict(list)
for name, subject in students:
groups[subject].append(name)
print(dict(groups))
# {'Math': ['Alice', 'Bob', 'Eve'], 'English': ['Charlie', 'David']}
# Способ 2: Функциональный подход с reduce
def group_by(data, key_func):
return reduce(
lambda acc, item: (
acc.update({key_func(item): acc.get(key_func(item), []) + [item]}) or acc
),
data,
{}
)
result = group_by(students, lambda x: x[1])
print(result)
3. Counter для анализа данных
from collections import Counter
from functools import reduce
# Подсчёт элементов
text = "hello world hello python"
words = text.split()
word_counts = Counter(words)
print(word_counts) # Counter({'hello': 2, 'world': 1, 'python': 1})
# Функциональный подход: фильтрация по частоте
frequent_words = list(filter(lambda x: x[1] > 1, word_counts.items()))
print(frequent_words) # [('hello', 2)]
# Map: получить только слова
words_only = list(map(lambda x: x[0], word_counts.items()))
print(words_only) # ['hello', 'world', 'python']
# Reduce: найти максимальную частоту
max_frequency = reduce(
lambda max_count, item: max(max_count, item[1]),
word_counts.items(),
0
)
print(max_frequency) # 2
# most_common: встроенный метод
print(word_counts.most_common(2)) # [('hello', 2), ('world', 1)]
4. deque для функционального обхода
from collections import deque
from functools import reduce
# Двусторонняя очередь
dq = deque([1, 2, 3, 4, 5])
# Функциональное преобразование
squared = list(map(lambda x: x ** 2, dq))
print(squared) # [1, 4, 9, 16, 25]
# Filter: чётные числа
evens = list(filter(lambda x: x % 2 == 0, dq))
print(evens) # [2, 4]
# Reduce: произведение
product = reduce(lambda a, b: a * b, dq)
print(product) # 120
# Ротация
dq.rotate(2) # Сдвиг вправо на 2
print(list(dq)) # [4, 5, 1, 2, 3]
5. ChainMap для функциональной работы со словарями
from collections import ChainMap
# Объединение словарей
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = {'e': 5}
chained = ChainMap(dict1, dict2, dict3)
# Функциональное преобразование
transformed = {k: v * 2 for k, v in chained.items()}
print(transformed) # {'a': 2, 'b': 4, 'c': 6, 'd': 8, 'e': 10}
# Map на keys и values
keys = list(map(str.upper, chained.keys()))
print(keys) # ['A', 'B', 'C', 'D', 'E']
6. Комбинирование с functools
from collections import Counter, defaultdict
from functools import reduce, partial
# Анализ текста: найти top-3 буквы
text = "the quick brown fox"
letters = Counter(text.replace(' ', ''))
# Через reduce
top_letters = dict(reduce(
lambda acc, item: acc + [item] if len(acc) < 3 else acc,
sorted(letters.items(), key=lambda x: -x[1]),
[]
))
print(top_letters) # Самые частые буквы
# Через встроенный метод
print(dict(letters.most_common(3)))
7. Пайплайн обработки данных
from collections import namedtuple, Counter, defaultdict
from functools import reduce
# Определение данных
Transaction = namedtuple('Transaction', ['id', 'amount', 'category'])
transactions = [
Transaction(1, 100, 'food'),
Transaction(2, 50, 'transport'),
Transaction(3, 200, 'food'),
Transaction(4, 75, 'entertainment'),
Transaction(5, 150, 'food'),
]
# Pipeline: фильтрация → группировка → агрегирование
# 1. Filter: только суммы > 75
expensive = list(filter(lambda t: t.amount > 75, transactions))
# 2. Map: преобразовать в (категория, сумма)
by_category = list(map(lambda t: (t.category, t.amount), expensive))
# 3. Reduce: сумма по категориям
totals = reduce(
lambda acc, item: {
**acc,
item[0]: acc.get(item[0], 0) + item[1]
},
by_category,
{}
)
print(totals) # {'food': 350, 'entertainment': 75}
# Альтернатива с defaultdict
totals_dd = defaultdict(int)
for category, amount in by_category:
totals_dd[category] += amount
print(dict(totals_dd))
8. Практический пример: обработка логов
from collections import Counter, namedtuple
from functools import reduce
LogEntry = namedtuple('LogEntry', ['timestamp', 'level', 'message'])
logs = [
LogEntry('10:00', 'INFO', 'User logged in'),
LogEntry('10:05', 'ERROR', 'Database connection failed'),
LogEntry('10:10', 'INFO', 'Cache cleared'),
LogEntry('10:15', 'ERROR', 'Invalid request'),
LogEntry('10:20', 'INFO', 'Report generated'),
]
# 1. Подсчитать ошибки
errors = list(filter(lambda log: log.level == 'ERROR', logs))
print(f"Total errors: {len(errors)}")
# 2. Группировать по уровню
from collections import defaultdict
grouped = defaultdict(list)
for log in logs:
grouped[log.level].append(log.message)
print(dict(grouped))
# 3. Map: извлечь только сообщения ошибок
error_messages = list(map(lambda log: log.message, errors))
print(error_messages)
# 4. Reduce: построить статистику
stats = reduce(
lambda acc, log: {**acc, log.level: acc.get(log.level, 0) + 1},
logs,
{}
)
print(stats) # {'INFO': 3, 'ERROR': 2}
Преимущества функционального подхода с collections
- Иммутабельность — namedtuple неизменяемы
- Composability — легко комбинировать функции
- Readability — декларативный стиль
- Testability — чистые функции легче тестировать
- Performance — оптимизация за счёт ленивых вычислений
Вывод: collections + функциональное программирование = мощный инструмент для обработки данных в Python, позволяющий писать чистый, выразительный и надёжный код.