web-dev-qa-db-ja.com

pythonの2つのパスを比較する

検討してください:

path1 = "c:/fold1/fold2"
list_of_paths = ["c:\\fold1\\fold2","c:\\temp\\temp123"]

if path1 in list_of_paths:
    print "found"

IfステートメントがTrueを返すことを望みますが、これは文字列比較であるため、Falseに評価されます。

スラッシュに関係なく、2つのパスを比較するにはどうすればよいですか?両方の文字列を共通の形式に変換するためにreplace関数を使用したくないのですが。

25
Jagannath Ks

_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では、パスを比較するためにmust_os.path.normcase_ を使用します。Windowsでは、パスでは大文字と小文字が区別されないためです。

26
falsetru

これらの回答はすべて_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):
    # ...
_
13

os.path モジュールには、同等のパスが同じ文字列に正規化されるように、ファイルパスを正規化するいくつかの関数が含まれています。 normpathnormcaseabspathsamefile、またはその他のツールが必要になる場合があります。

python- を使用している場合、 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
4
pkowalczyk

文字列ではなくリストとしてlist_of_pathsを保存します。

list_of_paths = [["c:","fold1","fold2"],["c","temp","temp123"]]

次に、指定されたパスを「/」または「\」(存在する方)で分割し、inキーワードを使用します。

2
Aswin Murugesh

使用する os.path.normpath比較する前にパスを正規化します。例えば:

if any(os.path.normpath(path1) == os.path.normpath(p)
       for p in list_of_paths):
    print "found"
2
user4815162342