В этом уроке мы попрактикуемся еще с одним вариантом агрегации данных на файловых системах.
Условие задачи
Напишем функцию, которая принимает на вход директорию и возвращает:
- Список директорий первого уровня вложенности
- Количество файлов внутри каждой из них, включая все поддиректории
Так это выглядит в коде:
from hexlet import fs
tree = fs.mkdir(
"/",
[
fs.mkdir(
"etc",
[
fs.mkdir("apache"),
fs.mkdir(
"nginx",
[
fs.mkfile("nginx.conf"),
],
),
],
),
fs.mkdir(
"consul",
[
fs.mkfile("config.json"),
fs.mkfile("file.tmp"),
fs.mkdir("data"),
],
),
fs.mkfile("hosts"),
fs.mkfile("resolve"),
],
)
print(get_subdirectories_info(tree))
# => [('etc', 1), ('consul', 2)]
https://repl.it/@hexlet/python-trees-search-get-subdirectories-info
Реализация
Внутри себя эта задача распадается на две:
- Подсчет количества файлов внутри директории
- Вызов функции подсчета файлов на каждой из поддиректорий
Начнем с подсчета количества файлов. Это классическая задача на агрегацию:
def get_files_count(node):
if fs.is_file(node):
return 1
children = fs.get_children(node)
descendant_count = list(map(get_files_count, children))
return sum(descendant_count)
Следующий шаг — извлечь всех потомков из исходного узла и к каждому из них применить подсчет:
def get_subdirectories_info(node):
children = fs.get_children(node)
# Нас интересуют только директории
filtered = filter(fs.is_directory, children)
# Запускаем подсчет для каждой директории
result = map(
lambda child: (fs.get_name(child), get_files_count(child)),
filtered,
)
return list(result)
В коде выше мы обратились к потомкам напрямую. Сначала мы отфильтровали их, а затем выполнили отображение на необходимый массив, содержащий для каждой директории имя и количество файлов в нем.

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.