Comparing two paths in python

31,628

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 , you can use 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.

Share:
31,628
Jagannath Ks
Author by

Jagannath Ks

Updated on January 21, 2021

Comments

  • Jagannath Ks
    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 to False, 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
    Jagannath Ks over 10 years
    Hi 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
    ondra over 10 years
    And add os.path.normcase to convert to lowercase on windows - as windows should be case insensitive for comparisons.
  • Aswin Murugesh
    Aswin Murugesh over 10 years
    But the OP says there may be any of the slashes in any place
  • falsetru
    falsetru over 10 years
    @AswinMurugesh, Thank you for comment. I added a version that will handle such case.
  • Jagannath Ks
    Jagannath Ks over 10 years
    list1 = ['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
    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 directorys a\b\c, x\y\z
  • cbare
    cbare over 8 years
    There'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
    Seng Cheong over 7 years
    I think you want to use os.path.realpath, to cover cases like @cbare mentions.
  • baky
    baky over 7 years
    os.path.normpath is for normalizing the paths, we should use os.path.realpath for canonicalizing.
  • user4815162342
    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
    mattst over 4 years
    +1 for os.path.samefile(path1, path2). Using this removes the need to use normpath(), realpath(), or normcase() (on Windows OSes), before performing a string comparrison. However it requires both paths to exist on the filesystem or a FileNotFoundError exception will be raised and it does not resolve home relative paths, e.g. ~/Path/To/File, for these use expanduser(). Note: Python 3.2 added samefile() support for Windows OSes.
  • Stefan
    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
    Guimoute over 2 years
    To 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".