os.path.commonprefix () и os.path.relpath () ваши друзья:
>>> print os.path.commonprefix(['/usr/var/log', '/usr/var/security'])
'/usr/var'
>>> print os.path.commonprefix(['/tmp', '/usr/var']) # No common prefix: the root is the common prefix
'/'
Таким образом, вы можете проверить, является ли общий префикс одним из путей, т.е. является ли один из путей общим предком:
paths = […, …, …]
common_prefix = os.path.commonprefix(list_of_paths)
if common_prefix in paths:
…
Затем вы можете найти относительные пути:
relative_paths = [os.path.relpath(path, common_prefix) for path in paths]
С помощью этого метода вы даже можете обрабатывать более двух путей и проверить, все ли пути ниже одного из них.
PS : в зависимости от того, как выглядят ваши пути, вы можете сначала выполнить некоторую нормализацию (это полезно в ситуациях, когда неизвестно, заканчиваются ли они всегда символом «/» или нет, или если некоторые пути являются относительными). Соответствующие функции включают os.path.abspath () и os.path.normpath () .
PPS : как упоминал Питер Бриггс в комментариях, простой подход, описанный выше, может потерпеть неудачу:
>>> os.path.commonprefix(['/usr/var', '/usr/var2/log'])
'/usr/var'
хотя /usr/varэто не общий префикс путей. Принудительное завершение всех путей знаком «/» перед вызовом commonprefix()решает эту (специфическую) проблему.
PPPS : как упоминалось в bluenote10, добавление косой черты не решает общую проблему. Вот его следующий вопрос: Как обойти ошибку os.path.commonprefix Python?
PPPPS : начиная с Python 3.4, у нас есть pathlib , модуль, который обеспечивает более разумную среду манипулирования путями. Я предполагаю, что общий префикс набора путей может быть получен, получая все префиксы каждого пути (с PurePath.parents()), беря пересечение всех этих родительских наборов, и выбирая самый длинный общий префикс.
PPPPPS : Python 3.5 представил правильное решение этого вопроса: os.path.commonpath()возвращает правильный путь.