Pergunta

Eu quero ser capaz de listar apenas os diretórios dentro alguma pasta. Isso significa que eu não quero nomes de arquivos listados, nem quero subpastas adicionais.

Vamos ver se um exemplo ajuda. No diretório atual, temos:

>>> 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']

No entanto, eu não quero nomes de arquivos listados. Nem quero sub-pastas, como maldições \ lib \. Essencialmente o que eu quero funciona com o seguinte:

>>> for root, dirnames, filenames in os.walk('.'):
...     print dirnames
...     break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']

No entanto, eu estou querendo saber se existe uma maneira mais simples de alcançar os mesmos resultados. Tenho a impressão de que o uso de os.walk apenas para retornar ao nível superior é ineficiente / demais. |

Foi útil?

Solução

Filtrar o resultado usando os.path.isdir () (e uso os.path.join () para obter o caminho real):

>>> [ 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']

Outras dicas

os.walk

Use os.walk com next função artigo:

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

Para Python <= 2,5 uso:

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

Como isso funciona

os.walk é um gerador e chamando next vai ter o primeiro resultado na forma de um 3-tupla (dirPath, dirnames, nomes de arquivos). Assim o índice [1] retorna apenas o dirnames de que tupla.

Filtrar a lista usando os.path.isdir para detectar diretórios.

filter(os.path.isdir, os.listdir(os.getcwd()))
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]

Note-se que, em vez de fazer os.listdir(os.getcwd()), é preferível fazer os.listdir(os.path.curdir). menos uma chamada de função, e é tão portátil.

Assim, para completar a resposta, para obter uma lista de diretórios em uma pasta:

def listdirs(folder):
    return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

Se você preferir caminhos completos, em seguida, usar essa função:

def listdirs(folder):
    return [
        d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
        if os.path.isdir(d)
    ]

Só para acrescentar que o uso os.listdir () não "ter um monte de processamento vs os.walk muito simples (). Next () [1]" . Isso ocorre porque os.walk () usa os.listdir () internamente. Na verdade, se você testá-los juntos:

>>>> 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

A filtragem de os.listdir () é ligeiramente mais rápido.

Uma maneira muito mais simples e elegante é usar este:

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

Executar este script na mesma pasta para a qual deseja pasta names.It lhe dará exatamente as pastas imediatos citar somente (que também sem o caminho completo das pastas).

Isso parece funcionar muito (pelo menos no linux):

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

sendo um novato aqui eu não posso comentar ainda diretamente, mas aqui é uma pequena correção eu gostaria de adicionar a seguinte parte de o ??O????? resposta :

Se você preferir caminhos completos, em seguida, usar essa função:

def listdirs(folder):  
  return [
    d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
    if os.path.isdir(d)
]

para aqueles que ainda estão em python <2.4 : as necessidades construto internas para ser uma lista em vez de uma tupla e, portanto, deve ler como este:

def listdirs(folder):  
  return [
    d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
    if os.path.isdir(d)
  ]

caso contrário, recebe um erro de sintaxe.

Usando compreensão da lista,

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

Eu acho que é a maneira mais simples

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

Para obter uma lista de nomes de caminho completos prefiro esta versão para as outras soluções aqui:

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

A mais segura opção que não falha quando não há nenhum diretório.

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 []

Como assim?

>>>> [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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top