Рекурсивный поиск файлов по подпапкам в Python: os.walk()
Быстрый ответ
Для получения всех файлов в директории и её поддиректориях в Python вы можете воспользоваться функцией os.walk()
. Приведенный ниже код при помощи спискового включения создаст список путей ко всем файлам:
import os
def get_file_paths(directory):
return [os.path.join(root, filename) for root, _, files in os.walk(directory) for filename in files]
# Пример использования
file_paths = get_file_paths('your/directory')
Функция get_file_paths
вернет список, содержащий пути ко всем файлам в заданной директории.
Завершение
Если вам требуется оптимизировать использование памяти при работе с обширными директориями, то предпочтительно использовать генераторы, а не список. Генераторы выдают элементы по одному, не загружая при этом все элементы в память одновременно.
def get_file_paths_gen(directory):
for root, _, files in os.walk(directory):
for file in files:
yield os.path.join(root, file)
Визуализация
Современный и удобный способ обработки путей к файлам — это использование модуля pathlib
, который стал доступен начиная с Python 3.4. Он позволяет проводить поиск по шаблону и реализовывать рекурсивный поиск файла при помощи символа **
.
from pathlib import Path
def get_file_paths_pattern(directory, pattern="*"):
return [str(path) for path in Path(directory).rglob(pattern)]
# Пример использования (выборка всех .txt файлов)
txt_files = get_file_paths_pattern('your/directory', '*.txt')
Полезные материалы
Для ещё более быстрой выборки файлов можно воспользоваться функцией os.scandir()
вместо os.walk()
, доступной начиная с Python 3.5. Эта функция обеспечивает быстрее итерацию по содержимому директорий.
from os import scandir
def get_file_paths_scandir(directory):
entries = list(scandir(directory))
files_in_directory = [entry.path for entry in entries if entry.is_file()]
dirs_in_directory = [entry.path for entry in entries if entry.is_dir()]
for sub_directory in dirs_in_directory:
files_in_directory.extend(get_file_paths_scandir(sub_directory))
return files_in_directory
Очистка списка: Исключение дубликатов
В вашем списке могут возникнуть дубликаты путей к файлам. Чтобы исключить их и получить список только уникальных путей, можно использовать множество:
def get_unique_file_paths(directory):
return list(set(get_file_paths(directory)))
Настройка поиска: Фильтрация по размеру файла
Иногда возникает необходимость фильтрации файлов по размеру или другим параметрам. Ниже приведен способ модификации функции рекурсивного поиска для реализации такой фильтрации:
def get_file_paths_filter(directory, min_size=0):
return [
os.path.join(root, file) for root, _, filenames in os.walk(directory)
for file in filenames if os.path.getsize(os.path.join(root, file)) >= min_size
]
Полезные материалы
- os — Перечисление функций для работы с операционной системой — Документация Python 3.12.2
- glob — Осуществление поиска файла по шаблону в стиле Unix — Документация Python 3.12.2
- pathlib — Ориентированные на объекты пути файловой системы — Документация Python 3.12.2
- Модуль pathlib в Python: Тонкости работы с файловой системой – Real Python
- fnmatch — Совместимость имени файла в стиле Unix со шаблоном — Документация Python 3.12.2
- shutil — Высокоуровневые операции с файлами — Документация Python 3.12.2
- Работа с множественным присваиванием и распаковкой кортежей для улучшения читаемости кода на Python