Сравнение двух путей в python
Рассмотрим:
path1 = "c:/fold1/fold2"
list_of_paths = ["c:\\fold1\\fold2","c:\\temp\\temp123"]
if path1 in list_of_paths:
print "found"
Я бы хотел, чтобы оператор if возвращал True
, но он оценивается как False
,
так как это сравнение строк.
Как сравнить два пути независимо от прямой или обратной косой черты, которую они имеют? Я бы предпочел не использовать функцию replace
для преобразования обеих строк в общий формат.
Ответы
Ответ 1
Используйте os.path.normpath
для преобразования c:/fold1/fold2
в c:\fold1\fold2
:
>>> path1 = "c:/fold1/fold2"
>>> list_of_paths = ["c:\\fold1\\fold2","c:\\temp\\temp123"]
>>> os.path.normpath(path1)
'c:\\fold1\\fold2'
>>> os.path.normpath(path1) in list_of_paths
True
>>> os.path.normpath(path1) in (os.path.normpath(p) for p in list_of_paths)
True
os.path.normpath(path1) in map(os.path.normpath, list_of_paths)
также работает, но он создает список с целыми элементами пути, даже если они совпадают в середине. (В Python 2.x)
В Windows вы должны использовать os.path.normcase
для сравнения путей, потому что в Windows пути не чувствительны к регистру.
Ответ 2
Во всех этих ответах упоминается os.path.normpath
, но ни в одном из них не упоминается os.path.realpath
:
os.path.realpath(path)
Возвращает канонический путь указанного имени файла, исключая любые символические ссылки, встречающиеся в пути (если они поддерживаются операционной системой).
Новое в версии 2.2.
Итак:
if os.path.realpath(path1) in (os.path.realpath(p) for p in list_of_paths):
# ...
Ответ 3
Модуль os.path
содержит несколько функций для нормализации пути к файлу, чтобы эквивалентные пути нормализовались к одной и той же строке. Вы можете захотеть normpath
, normcase
, abspath
, samefile
или какой-либо другой инструмент.
Ответ 4
Если вы используете python-3, вы можете использовать pathlib для достижения своей цели:
import pathlib
path1 = pathlib.Path("c:/fold1/fold2")
list_of_paths = [pathlib.Path(path) for path in ["c:\\fold1\\fold2","c:\\temp\\temp123"]]
assert path1 in list_of_paths
Ответ 5
Сохраните список_событий как список вместо строки:
list_of_paths = [["c:","fold1","fold2"],["c","temp","temp123"]]
Затем разделите заданный путь на '/' или '\' (в зависимости от того, что присутствует), а затем используйте ключевое слово in
.
Ответ 6
Используйте os.path.normpath
для канонизации путей перед их сопоставлением. Например:
if any(os.path.normpath(path1) == os.path.normpath(p)
for p in list_of_paths):
print "found"