Pythonでトップレベルのディレクトリのみをリストするにはどうすればよいですか?
-
02-07-2019 - |
質問
いくつかのフォルダ内のディレクトリのみを一覧表示できるようにしたい。 つまり、ファイル名を一覧表示したり、サブフォルダーを追加したりする必要はありません。
例が役立つかどうか見てみましょう。現在のディレクトリには次のものがあります。
>>> os.listdir(os.getcwd())
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'mod_p
ython-wininst.log', 'NEWS.txt', 'pymssql-wininst.log', 'python.exe', 'pythonw.ex
e', 'README.txt', 'Removemod_python.exe', 'Removepymssql.exe', 'Scripts', 'tcl',
'Tools', 'w9xpopen.exe']
ただし、ファイル名を一覧表示したくない。 \ Lib \ cursesなどのサブフォルダーも必要ありません。基本的に、私が望むものは以下で動作します:
>>> for root, dirnames, filenames in os.walk('.'):
... print dirnames
... break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']
しかし、同じ結果を得るためのもっと簡単な方法があるのだろうかと思っています。 os.walkを使用してトップレベルを返すだけでは効率が悪い/多すぎるという印象を受けます。
解決
os.path.isdir()を使用して結果をフィルタリングします(そしてos.path.join()を使用して実際のパスを取得します):
>>> [ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]
['ctypes', 'distutils', 'encodings', 'lib-tk', 'config', 'idlelib', 'xml', 'bsddb', 'hotshot', 'logging', 'doc', 'test', 'compiler', 'curses', 'site-packages', 'email', 'sqlite3', 'lib-dynload', 'wsgiref', 'plat-linux2', 'plat-mac']
他のヒント
os.path.isdirを使用してリストをフィルタリングし、ディレクトリを検出します。
filter(os.path.isdir, os.listdir(os.getcwd()))
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
os.listdir(os.getcwd())
を実行する代わりに、os.listdir(os.path.curdir)
を実行することをお勧めします。関数呼び出しが1つ少なくなり、移植性が高まります。
つまり、答えを完成させるために、フォルダ内のディレクトリのリストを取得するには:
def listdirs(folder):
return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
フルパス名が必要な場合は、次の関数を使用します:
def listdirs(folder):
return [
d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
if os.path.isdir(d)
]
os.listdir()を使用しても <!> quot;ではなく、非常に単純なos.walk()。next()[1] <!> quot; で多くの処理を行うことを追加するだけです。これは、os.walk()が内部でos.listdir()を使用するためです。実際、それらを一緒にテストする場合:
>>>> import timeit
>>>> timeit.timeit("os.walk('.').next()[1]", "import os", number=10000)
1.1215229034423828
>>>> timeit.timeit("[ name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) ]", "import os", number=10000)
1.0592019557952881
os.listdir()のフィルタリングはわずかに高速です。
非常にシンプルでエレガントな方法は、これを使用することです:
import os
dir_list = os.walk('.').next()[1]
print dir_list
このスクリプトは、フォルダー名が必要なフォルダーと同じフォルダーで実行します。フォルダーの完全パスを除いた、直接のフォルダー名のみが表示されます。
これも動作するようです(少なくともLinuxでは):
import glob, os
glob.glob('*' + os.path.sep)
ここで初心者なので、まだ直接コメントすることはできませんが、ここで <!>#932; <!>#918; <!>#937; <!>#932; <!>#918 ; <!>#921; <!>#927; <!>#933; 's answer :
フルパス名が必要な場合は、次の関数を使用します:
def listdirs(folder): return [ d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder)) if os.path.isdir(d) ]
まだPythonを使用している場合<!> lt; 2.4 :内部構造はタプルではなくリストである必要があるため、次のようになります。
def listdirs(folder):
return [
d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
if os.path.isdir(d)
]
それ以外の場合、構文エラーが発生します。
リスト内包表記の使用、
[a for a in os.listdir() if os.path.isdir(a)]
これが最も簡単な方法だと思います
[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]
フルパス名のリストについては、他の解決策よりもこのバージョンの方が好まれています。
def listdirs(dir):
return [os.path.join(os.path.join(dir, x)) for x in os.listdir(dir)
if os.path.isdir(os.path.join(dir, x))]
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]
ディレクトリがない場合に失敗しない、より安全なオプション。
def listdirs(folder):
if os.path.exists(folder):
return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
else:
return []
そうですか?
>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
-- This will exclude files and traverse through 1 level of sub folders in the root
def list_files(dir):
List = []
filterstr = ' '
for root, dirs, files in os.walk(dir, topdown = True):
#r.append(root)
if (root == dir):
pass
elif filterstr in root:
#filterstr = ' '
pass
else:
filterstr = root
#print(root)
for name in files:
print(root)
print(dirs)
List.append(os.path.join(root,name))
#print(os.path.join(root,name),"\n")
print(List,"\n")
return List