web-dev-qa-db-ja.com

Pythonでトップレベルのディレクトリのみをリストするにはどうすればよいですか?

フォルダー内のディレクトリのみを一覧表示できるようにしたい。これは、ファイル名を一覧表示したり、追加のサブフォルダが必要ないことを意味します。

例が役立つかどうか見てみましょう。現在のディレクトリには次のものがあります。

>>> 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を使用してトップレベルを返すだけでは効率が悪い/多すぎるという印象を受けます。

108
fuentesjr

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']
100
Thomas Wouters

os.walk

つかいます - os.walk with next アイテム関数:

next(os.walk('.'))[1]

Python <= 2.5の場合:

os.walk('.').next()[1]

仕組み

os.walkはジェネレーターであり、nextを呼び出すと、最初の結果が3タプル(dirpath、dirnames、filenames)の形式で取得されます。したがって、[1]インデックスは、そのタプルからdirnamesのみを返します。

163
Alex Coventry

Os.path.isdirを使用してリストをフィルタリングし、ディレクトリを検出します。

filter(os.path.isdir, os.listdir(os.getcwd()))
43
Colin Jensen
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
12
Mark Roddy

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)
    ]
10
tzot

Os.listdir()を使用して追加するだけではありません"非常に単純なos.walk()。next()[1]"。これは、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()のフィルタリングは非常にわずかに高速です。

8
foz

非常にシンプルでエレガントな方法は、これを使用することです:

 import os
 dir_list = os.walk('.').next()[1]
 print dir_list

フォルダー名が必要なフォルダーと同じフォルダーでこのスクリプトを実行します。フォルダーの完全なパスを除いて、フォルダー名のみが正確に表示されます。

6
manty

これも動作するようです(少なくともLinuxでは):

import glob, os
glob.glob('*' + os.path.sep)
5
Travis

リスト内包表記を使用して、

[a for a in os.listdir() if os.path.isdir(a)]

一番簡単な方法だと思う

2
KBLee

ここでは初心者なので、まだ直接コメントすることはできませんが、ここでは ΤΖΩΤΖΙΟΥ'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 <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)
  ]

そうしないと、構文エラーが発生します。

2
antiplex
[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]
1
Moe

完全なパス名のリストについては、他の solutions よりもこのバージョンの方が好きです:

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))]
1
Malius Arth
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]
1
nvd

そのようです?

>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
0
Kirk Strauser

ディレクトリがないときに失敗しない、より安全なオプション。

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 []
0
Alexey Gavrilov