Comparing two paths in python
Solution 1
Use os.path.normpath
to convert c:/fold1/fold2
to 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)
also works, but it will build a list with entire path items even though there's match in the middle. (In Python 2.x)
On Windows, you must use os.path.normcase
to compare paths because on Windows, paths are not case-sensitive.
Solution 2
All of these answers mention os.path.normpath
, but none of them mention os.path.realpath
:
os.path.realpath(path)
Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path (if they are supported by the operating system).
New in version 2.2.
So then:
if os.path.realpath(path1) in (os.path.realpath(p) for p in list_of_paths):
# ...
Solution 3
The os.path
module contains several functions to normalize file paths so that equivalent paths normalize to the same string. You may want normpath
, normcase
, abspath
, samefile
, or some other tool.
Solution 4
If you are using python-3, you can use pathlib to achieve your goal:
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
Solution 5
Store the list_of_paths as a list instead of a string:
list_of_paths = [["c:","fold1","fold2"],["c","temp","temp123"]]
Then split given path by '/' or '\' (whichever is present) and then use the in
keyword.
Jagannath Ks
Updated on January 21, 2021Comments
-
Jagannath Ks over 3 years
Consider:
path1 = "c:/fold1/fold2" list_of_paths = ["c:\\fold1\\fold2","c:\\temp\\temp123"] if path1 in list_of_paths: print "found"
I would like the if statement to return
True
, but it evaluates toFalse
, since it is a string comparison.How to compare two paths irrespective of the forward or backward slashes they have? I'd prefer not to use the
replace
function to convert both strings to a common format. -
Jagannath Ks over 10 yearsHi Ashwin, I am not sure which variable has what slash as both are generated dynamically and i cannot replace every string as i would be surfing large data
-
ondra over 10 yearsAnd add os.path.normcase to convert to lowercase on windows - as windows should be case insensitive for comparisons.
-
Aswin Murugesh over 10 yearsBut the OP says there may be any of the slashes in any place
-
falsetru over 10 years@AswinMurugesh, Thank you for comment. I added a version that will handle such case.
-
Jagannath Ks over 10 yearslist1 = ['a\\b\\c','x\y\z'], list2 = ['a\\b','x\y'], lis3 = [os.path.normpath(item) for item in list1 if os.path.isdir(item)], list4 = [os.path.normpath(item) for item in list2 if os.path.isdir(item)] for directory in list4: for root, dirnames, filenames in os.walk(directory): if os.path.normpath(root) in list3: print "found" but this code somehow fails !
-
falsetru over 10 years@JagannathKs, It works for me (printing
found
) after slight modification (lis3
->list3
,x\y
->x\\y
,x\y\z
->x\\y\\z
) and creation of the directorysa\b\c
,x\y\z
-
cbare over 8 yearsThere's still a gotcha on windows: 'c:\\users\\administrator\\foo.txt' is the same file as 'c:\\users\\admini~1\\foo.txt' thanks to the lameness that is 8.3 filenames.
-
Seng Cheong over 7 yearsI think you want to use
os.path.realpath
, to cover cases like @cbare mentions. -
baky over 7 yearsos.path.normpath is for normalizing the paths, we should use os.path.realpath for canonicalizing.
-
user4815162342 over 7 years@baky That depends on the exact requirements. Since the OP requested comparison "irrespective of forward or backward slash", which
normpath
fulfills. It is of course possible that the OP misstated their requirements two and a half years ago, but that would be guessing. -
mattst over 4 years+1 for
os.path.samefile(path1, path2)
. Using this removes the need to usenormpath()
,realpath()
, ornormcase()
(on Windows OSes), before performing a string comparrison. However it requires both paths to exist on the filesystem or aFileNotFoundError
exception will be raised and it does not resolve home relative paths, e.g.~/Path/To/File
, for these useexpanduser()
. Note: Python 3.2 addedsamefile()
support for Windows OSes. -
Stefan almost 3 years+1 also for samefile and just to mention: despite the name "samefile" also allows for checking directories! see docs.python.org/3/library/os.path.html
-
Guimoute over 2 yearsTo add on @falsetru's answer, the nice thing about this solution is that it understands when you move to the parent folder, so
os.path.normpath("A\\B\\C\\..\\..\\test.txt") == "A\\test.txt"
.