Если я правильно понимаю, вы не хотите находить каталоги с таким же базовым именем , это так? Если да, то это должно сработать:
import os
from collections import deque
from typing import List, Set
def scandir_only_dirs(path: str) -> List[str]:
return [f.path for f in os.scandir(path) if f.is_dir()]
def scandir_no_same_basename(path: str) -> Set[str]:
result = set()
queue = deque(scandir_only_dirs(path))
if not queue:
return result
visited_basenames = set()
while queue:
currdir = queue.popleft()
basename = os.path.basename(currdir)
if basename not in visited_basenames:
result.add(currdir)
queue.extendleft(scandir_only_dirs(currdir))
visited_basenames.add(basename)
return result
В вашем примере дерева каталогов эта функция возвращает:
{'.\\build',
'.\\build\\sth1',
'.\\build\\sth2',
'.\\build\\sth2\\6.11.2',
'.\\build\\sth2\\6.11.3',
'.\\common'}
Этот алгоритм, конечно, можно изменить в зависимости от того, хотите ли выследует принять во внимание какую-то другую часть, кроме basename
, но общая идея состоит в том, чтобы выполнить обход и установить, каковы ваши критерии для "посещения".
Изменить
Добавление ответа ниже, потому что я неправильно понял вопрос:
def find_paths_to_dir(dir_basename: str, from_path: str=".") -> Set[str]:
result = set()
queue = deque(scandir_only_dirs(from_path))
if not queue:
return result
while queue:
currdir = queue.popleft()
basename = os.path.basename(currdir)
if basename == dir_basename:
result.add(currdir)
else:
queue.extendleft(scandir_only_dirs(currdir))
return result