varios - listar pastas e subpastas python




Como faço para listar todos os arquivos de um diretório? (20)

Obter uma lista de arquivos com o Python 2 e 3

Eu também fiz um pequeno vídeo aqui: Python: como obter uma lista de arquivos em um diretório

os.listdir ()

ou ..... como obter todos os arquivos (e diretórios) no diretório atual (Python 3)

A maneira mais simples de ter o arquivo no diretório atual no Python 3 é essa. É muito simples; use o módulo os e a função listdir () e você terá o arquivo nesse diretório (e eventuais pastas que estão no diretório, mas você não terá o arquivo no subdiretório, para que você possa usar o walk - eu irei fale sobre isso depois).

>>> import os
>>> arr = os.listdir()
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Usando glob

Achei glob mais fácil selecionar arquivo do mesmo tipo ou com algo em comum. Veja o seguinte exemplo:

import glob

txtfiles = []
for file in glob.glob("*.txt"):
    txtfiles.append(file)

Usando a compreensão da lista

import glob

mylist = [f for f in glob.glob("*.txt")]

Obtendo o nome do caminho completo com os.path.abspath

Como você percebeu, você não tem o caminho completo do arquivo no código acima. Se você precisa ter o caminho absoluto, você pode usar outra função do módulo _getfullpathname chamada _getfullpathname , colocando o arquivo que você obtém de os.listdir() como um argumento. Existem outras maneiras de ter o caminho completo, como veremos mais tarde (eu substituí, como sugerido por mexmex, _getfullpathname com abspath ).

>>> import os
>>> files_path = [os.path.abspath(x) for x in os.listdir()]
>>> files_path
['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']

Obter o nome do caminho completo de um tipo de arquivo em todos os subdiretórios com caminhada

Acho isso muito útil para encontrar coisas em muitos diretórios, e isso me ajudou a encontrar um arquivo sobre o qual eu não lembrava o nome:

import os

# Getting the current work directory (cwd)
thisdir = os.getcwd()

# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
    for file in f:
        if ".docx" in file:
            print(os.path.join(r, file))

os.listdir (): obtém arquivos no diretório atual (Python 2)

No Python 2 você, se você quiser a lista dos arquivos no diretório atual, você tem que dar o argumento como '.' ou os.getcwd () no método os.listdir.

>>> import os
>>> arr = os.listdir('.')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Para subir na árvore de diretórios

>>> # Method 1
>>> x = os.listdir('..')

# Method 2
>>> x= os.listdir('/')

Obter arquivos: os.listdir () em um diretório específico (Python 2 e 3)

>>> import os
>>> arr = os.listdir('F:\\python')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Obter arquivos de um subdiretório específico com os.listdir ()

import os

x = os.listdir("./content")

os.walk ('.') - diretório atual

>>> import os
>>> arr = next(os.walk('.'))[2]
>>> arr
['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']

módulo glob - todos os arquivos

import glob
print(glob.glob("*"))

out:['content', 'start.py']

next (os.walk ('.')) e os.path.join ('dir', 'file')

>>> import os
>>> arr = []
>>> for d,r,f in next(os.walk("F:\_python")):
>>>     for file in f:
>>>         arr.append(os.path.join(r,file))
...
>>> for f in arr:
>>>     print(files)

>output

F:\\_python\\dict_class.py
F:\\_python\\programmi.txt

next (os.walk ('F: \') - obtém o caminho completo - compreensão da lista

>>> [os.path.join(r,file) for r,d,f in next(os.walk("F:\\_python")) for file in f]
['F:\\_python\\dict_class.py', 'F:\\_python\\programmi.txt']

os.walk - get full path - todos os arquivos em sub dirs

x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]

>>>x
['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']

os.listdir () - obtém apenas arquivos txt

>>> arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
>>> print(arr_txt)
['work.txt', '3ebooks.txt']

glob - obtém apenas arquivos txt

>>> import glob
>>> x = glob.glob("*.txt")
>>> x
['ale.txt', 'alunni2015.txt', 'assenze.text.txt', 'text2.txt', 'untitled.txt']

Usando glob para obter o caminho completo dos arquivos

Se eu precisar do caminho absoluto dos arquivos:

>>> from path import path
>>> from glob import glob
>>> x = [path(f).abspath() for f in glob("F:\*.txt")]
>>> for f in x:
...  print(f)
...
F:\acquistionline.txt
F:\acquisti_2018.txt
F:\bootstrap_jquery_ecc.txt

Outro uso do glob

Se eu quiser todos os arquivos no diretório:

>>> x = glob.glob("*")

Usando os.path.isfile para evitar diretórios na lista

import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)

> output

['a simple game.py', 'data.txt', 'decorator.py']

Usando o pathlib do (Python 3.4)

import pathlib

>>> flist = []
>>> for p in pathlib.Path('.').iterdir():
...  if p.is_file():
...   print(p)
...   flist.append(p)
...
error.PNG
exemaker.bat
guiprova.mp3
setup.py
speak_gui2.py
thumb.PNG

Se você quiser usar a compreensão da lista

>>> flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]

* Você também pode usar apenas pathlib.Path () em vez de pathlib.Path (".")

Use o método glob em pathlib.Path ()

import pathlib

py = pathlib.Path().glob("*.py")
for file in py:
    print(file)

saída:

stack_overflow_list.py
stack_overflow_list_tkinter.py

Obter todos e apenas arquivos com os.walk

import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
    for f in t:
        y.append(f)

>>> y
['append_to_list.py', 'data.txt', 'data1.txt', 'data2.txt', 'data_180617', 'os_walk.py', 'READ2.py', 'read_data.py', 'somma_defaltdic.py', 'substitute_words.py', 'sum_data.py', 'data.txt', 'data1.txt', 'data_180617']

Obter apenas arquivos com o próximo e andar em um diretório

>>> import os
>>> x = next(os.walk('F://python'))[2]
>>> x
['calculator.bat','calculator.py']

Obtenha apenas diretórios com next e ande em um diretório

>>> import os
>>> next(os.walk('F://python'))[1] # for the current dir use ('.')
['python3','others']

Obter todos os nomes dos subdiretórios a pé

>>> for r,d,f in os.walk("F:\_python"):
...  for dirs in d:
...   print(dirs)
...
.vscode
pyexcel
pyschool.py
subtitles
_metaprogramming
.ipynb_checkpoints

os.scandir () do Python 3.5 em

>>> import os
>>> x = [f.name for f in os.scandir() if f.is_file()]
>>> x
['calculator.bat','calculator.py']

# Another example with scandir (a little variation from docs.python.org)
# This one is more efficient than os.listdir.
# In this case, it shows the files only in the current directory
# where the script is executed.

>>> import os
>>> with os.scandir() as i:
...  for entry in i:
...   if entry.is_file():
...    print(entry.name)
...
ebookmaker.py
error.PNG
exemaker.bat
guiprova.mp3
setup.py
speakgui4.py
speak_gui2.py
speak_gui3.py
thumb.PNG
>>>

Ex. 1: Quantos arquivos existem nos subdiretórios?

Neste exemplo, procuramos o número de arquivos incluídos em todo o diretório e em seus subdiretórios.

import os

def count(dir, counter=0):
    "returns number of files in dir and subdirs"
    for pack in os.walk(dir):
        for f in pack[2]:
            counter += 1
    return dir + " : " + str(counter) + "files"

print(count("F:\\python"))

> output

>'F:\\\python' : 12057 files'

Ex.2: Como copiar todos os arquivos de um diretório para outro?

Um script para fazer com que o seu computador encontre todos os arquivos de um tipo (padrão: pptx) e copie-os em uma nova pasta.

import os
import shutil
from path import path

destination = "F:\\file_copied"
# os.makedirs(destination)

def copyfile(dir, filetype='pptx', counter=0):
    "Searches for pptx (or other - pptx is the default) files and copies them"
    for pack in os.walk(dir):
        for f in pack[2]:
            if f.endswith(filetype):
                fullpath = pack[0] + "\\" + f
                print(fullpath)
                shutil.copy(fullpath, destination)
                counter += 1
    if counter > 0:
        print("------------------------")
        print("\t==> Found in: `" + dir + "` : " + str(counter) + " files\n")

for dir in os.listdir():
    "searches for folders that starts with `_`"
    if dir[0] == '_':
        # copyfile(dir, filetype='pdf')
        copyfile(dir, filetype='txt')


> Output

_compiti18\Compito Contabilità 1\conti.txt
_compiti18\Compito Contabilità 1\modula4.txt
_compiti18\Compito Contabilità 1\moduloa4.txt
------------------------
==> Found in: `_compiti18` : 3 files

Ex. 3: Como obter todos os arquivos em um arquivo txt

Caso você queira criar um arquivo txt com todos os nomes de arquivos:

import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
    for eachfile in os.listdir():
        mylist += eachfile + "\n"
    file.write(mylist)

Exemplo: txt com todos os arquivos de um disco rígido

"""We are going to save a txt file with all the files in your directory.
We will use the function walk()

"""

import os

# see all the methods of os
# print(*dir(os), sep=", ")
listafile = []
percorso = []
with open("lista_file.txt", "w", encoding='utf-8') as testo:
    for root, dirs, files in os.walk("D:\\"):
        for file in files:
            listafile.append(file)
            percorso.append(root + "\\" + file)
            testo.write(file + "\n")
listafile.sort()
print("N. of files", len(listafile))
with open("lista_file_ordinata.txt", "w", encoding="utf-8") as testo_ordinato:
    for file in listafile:
        testo_ordinato.write(file + "\n")

with open("percorso.txt", "w", encoding="utf-8") as file_percorso:
    for file in percorso:
        file_percorso.write(file + "\n")

os.system("lista_file.txt")
os.system("lista_file_ordinata.txt")
os.system("percorso.txt")

Todo o arquivo de C: \\ em um arquivo de texto

Esta é uma versão mais curta do código anterior. Altere a pasta onde começar a encontrar os arquivos, se você precisar começar de outra posição. Este código gera 50 mb em um arquivo de texto no meu computador com menos de 500.000 linhas com arquivos com o caminho completo.

import os

with open("file.txt", "w", encoding="utf-8") as filewrite:
    for r, d, f in os.walk("C:\\"):
        for file in f:
            filewrite.write(f"{r + file}\n")    

Uma função para procurar um determinado tipo de arquivo

importar os

def searchfiles(extension='.ttf'):
    "Create a txt file with all the file of a type"
    with open("file.txt", "w", encoding="utf-8") as filewrite:
        for r, d, f in os.walk("C:\\"):
            for file in f:
                if file.endswith(extension):
                    filewrite.write(f"{r + file}\n")

# looking for ttf file (fonts)
searchfiles('ttf')

Como posso listar todos os arquivos de um diretório em Python e adicioná-los a uma list ?


Parte um 1

Notas preliminares

  • Embora haja uma clara diferenciação entre os termos de arquivo e diretório no texto da pergunta, alguns podem argumentar que os diretórios são na verdade arquivos especiais
  • A declaração: " todos os arquivos de um diretório " podem ser interpretados de duas maneiras:
    1. Todos os descendentes diretos (ou de nível 1) apenas
    2. Todos os descendentes em toda a árvore de diretórios (incluindo os em subdiretórios)
  • Quando a pergunta foi feita, imagino que o Python 2 , fosse a versão LTS , no entanto, os exemplos de código serão executados pelo Python 3 ( .5 ) (vou mantê-los como compatível com Python 2 ; também, qualquer código pertencente a Python que eu vou postar, é da v3.5.4 - a menos que especificado de outra forma). Isso tem consequências relacionadas a outra palavra-chave na pergunta: " inclua-as em uma lista ":

    • Nas versões anteriores ao Python 2.2 , as seqüências (iteráveis) eram representadas principalmente por listas (tuplas, conjuntos, ...)
    • No Python 2.2 , o conceito de gerador ( [Python]: Generators ) - cortesia de [Python]: The yield statement ) - foi introduzido. Com o passar do tempo, as contrapartes do gerador começaram a aparecer para funções que retornavam / trabalhavam com listas
    • No Python 3 , o gerador é o comportamento padrão
    • Agora, eu não sei se retornar uma lista ainda é obrigatório (ou um gerador faria o mesmo), mas passando um gerador para o construtor de list , irá criar uma lista (e também consumi-la). O exemplo abaixo ilustra as diferenças em [Python]: map ( function, iterable, ... )
    Python 2.7.10 (default, Mar  8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> m = map(lambda x: x, [1, 2, 3])  # Just a dummy lambda function
    >>> m, type(m)
    ([1, 2, 3], <type 'list'>)
    >>> len(m)
    3
    


    Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> m = map(lambda x: x, [1, 2, 3])
    >>> m, type(m)
    (<map object at 0x000001B4257342B0>, <class 'map'>)
    >>> len(m)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'map' has no len()
    >>> lm0 = list(m)  # Construct a list out of the generator
    >>> lm0, type(lm0)
    ([1, 2, 3], <class 'list'>)
    >>>
    >>> lm1 = list(m)  # Construct a list out of the same generator
    >>> lm1, type(lm1)  # Empty list this time - generator already consumed
    ([], <class 'list'>)
    
  • Os exemplos serão baseados em um diretório chamado root_dir com a seguinte estrutura (este exemplo é para o Win , mas eu também copiei a árvore de pastas para o Ux ( Lnx )):

    E:\Work\Dev\\q003207219>tree /f "root_dir"
    Folder PATH listing for volume Work
    Volume serial number is 00000029 3655:6FED
    E:\WORK\DEV\\Q003207219\ROOT_DIR
    │   file0
    │   file1
    │
    ├───dir0
    │   ├───dir00
    │   │   │   file000
    │   │   │
    │   │   └───dir000
    │   │           file0000
    │   │
    │   ├───dir01
    │   │       file010
    │   │       file011
    │   │
    │   └───dir02
    │       └───dir020
    │           └───dir0200
    ├───dir1
    │       file10
    │       file11
    │       file12
    │
    ├───dir2
    │   │   file20
    │   │
    │   └───dir20
    │           file200
    │
    └───dir3
    


Soluções

Abordagens programáticas:

  1. [Python]: os. listdir ( path = '.' )

    Retorna uma lista contendo os nomes das entradas no diretório fornecido pelo caminho. A lista está em ordem arbitrária e não inclui as entradas especiais '.' e '..' ...


    >>> import os
    >>> root_dir = "root_dir"  # Path relative to current dir (os.getcwd())
    >>>
    >>> os.listdir(root_dir)  # List all the items in root_dir
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))]  # Filter the items and only keep files (strip out directories)
    ['file0', 'file1']
    

    Aqui está um exemplo mais elaborado ( code_os_listdir.py ):

    import os
    from pprint import pformat
    
    
    def _get_dir_content(path, include_folders, recursive):
        entries = os.listdir(path)
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    yield entry_with_path
                if recursive:
                    for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
                        yield sub_entry
            else:
                yield entry_with_path
    
    
    def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        for item in _get_dir_content(path, include_folders, recursive):
            yield item if prepend_folder_name else item[path_len:]
    
    
    def _get_dir_content_old(path, include_folders, recursive):
        entries = os.listdir(path)
        ret = list()
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    ret.append(entry_with_path)
                if recursive:
                    ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
            else:
                ret.append(entry_with_path)
        return ret
    
    
    def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
    
    
    def main():
        root_dir = "root_dir"
        ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
        lret0 = list(ret0)
        print(ret0, len(lret0), pformat(lret0))
        ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
        print(len(ret1), pformat(ret1))
    
    
    if __name__ == "__main__":
        main()
    

    Notas :

    • Existem duas implementações:
      • Um que usa geradores (claro que neste exemplo parece inútil, desde que eu converto o resultado imediatamente a uma lista)
      • O clássico (nomes de funções terminados em _old )
    • A recursão é usada (para entrar em subdiretórios)
    • Para cada implementação existem duas funções:
      • Um que começa com um sublinhado ( _ ): "privado" (não deve ser chamado diretamente) - que faz todo o trabalho
      • O público (wrapper anterior): ele apenas remove o caminho inicial (se necessário) das entradas retornadas. É uma implementação feia, mas é a única ideia que eu poderia ter neste momento
    • Em termos de desempenho, os geradores são geralmente um pouco mais rápidos (considerando os tempos de criação e de iteração ), mas eu não os testei em funções recursivas, e também estou interagindo com os geradores internos - não sei como o desempenho amigável é isso
    • Brinque com os argumentos para obter resultados diferentes


    Saída :

    (py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py"
    <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0',
     'root_dir\\dir0\\dir00',
     'root_dir\\dir0\\dir00\\dir000',
     'root_dir\\dir0\\dir00\\dir000\\file0000',
     'root_dir\\dir0\\dir00\\file000',
     'root_dir\\dir0\\dir01',
     'root_dir\\dir0\\dir01\\file010',
     'root_dir\\dir0\\dir01\\file011',
     'root_dir\\dir0\\dir02',
     'root_dir\\dir0\\dir02\\dir020',
     'root_dir\\dir0\\dir02\\dir020\\dir0200',
     'root_dir\\dir1',
     'root_dir\\dir1\\file10',
     'root_dir\\dir1\\file11',
     'root_dir\\dir1\\file12',
     'root_dir\\dir2',
     'root_dir\\dir2\\dir20',
     'root_dir\\dir2\\dir20\\file200',
     'root_dir\\dir2\\file20',
     'root_dir\\dir3',
     'root_dir\\file0',
     'root_dir\\file1']
    11 ['dir0\\dir00\\dir000\\file0000',
     'dir0\\dir00\\file000',
     'dir0\\dir01\\file010',
     'dir0\\dir01\\file011',
     'dir1\\file10',
     'dir1\\file11',
     'dir1\\file12',
     'dir2\\dir20\\file200',
     'dir2\\file20',
     'file0',
     'file1']
    


  1. [Python]: os. scandir ( path = '.' ) ( !!! Python 3.5 + !!! embora eu pense que para versões anteriores era um módulo separado (também portado para o Python 2 ))

    Retornar um iterador de objetos os.DirEntry correspondentes às entradas no diretório fornecido pelo caminho . As entradas são produzidas em ordem arbitrária e as entradas especiais '.' e '..' não estão incluídos.

    Usar scandir () em vez de listdir () pode aumentar significativamente o desempenho do código que também precisa do tipo de arquivo ou das informações de atributo do arquivo, porque os objetos os.DirEntry expõem essas informações se o sistema operacional fornecer isso ao varrer um diretório. Todos os métodos os.DirEntry podem executar uma chamada de sistema, mas is_dir() e is_file() geralmente requerem apenas uma chamada de sistema para links simbólicos; os.DirEntry.stat() sempre requer uma chamada de sistema no Unix, mas requer apenas um para links simbólicos no Windows.


    >>> import os
    >>> root_dir = os.path.join(".", "root_dir")  # Explicitly prepending current directory
    >>> root_dir
    '.\\root_dir'
    >>>
    >>> scandir_iterator = os.scandir(root_dir)
    >>> scandir_iterator
    <nt.ScandirIterator object at 0x00000268CF4BC140>
    >>> [item.path for item in scandir_iterator]
    ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1']
    >>>
    >>> [item.path for item in scandir_iterator]  # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension)
    []
    >>>
    >>> scandir_iterator = os.scandir(root_dir)  # Reinitialize the generator
    >>> for item in scandir_iterator :
    ...     if os.path.isfile(item.path):
    ...             print(item.name)
    ...
    file0
    file1
    

    Notas :

    • É semelhante a os.listdir
    • Mas também é mais flexível (e oferece mais funcionalidade), mais Python ic (e, em alguns casos, mais rápido)


  1. [Python]: os. walk ( top, topdown = True, onerror = Nenhum, followlinks = Falso )

    Gere os nomes de arquivos em uma árvore de diretórios percorrendo a árvore de cima para baixo ou de baixo para cima. Para cada diretório na árvore com raiz no diretório superior (incluindo top si), ele produz um 3-tupla ( dirpath, dirnames, filenames).


    >>> import os
    >>> root_dir = os.path.join(os.getcwd(), "root_dir")  # Specify the full path
    >>> root_dir
    'E:\\Work\\Dev\\\\q003207219\\root_dir'
    >>>
    >>> walk_generator = os.walk(root_dir)
    >>> root_dir_entry = next(walk_generator)  # First entry corresponds to the root dir (that was passed as an argument)
    >>> root_dir_entry
    ('E:\\Work\\Dev\\\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1'])
    >>>
    >>> root_dir_entry[1] + root_dir_entry[2]  # Display the dirs and the files (that are direct descendants) in a single list
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]]  # Display all the entries in the previous list by their full path
    ['E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file1']
    >>>
    >>> for entry in walk_generator:  # Display the rest of the elements (corresponding to every subdir)
    ...     print(entry)
    ...
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', ['dir20'], ['file20'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2\\dir20', [], ['file200'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', [], [])
    

    Notas :

    • Nos bastidores, usa os.listdir( os.scandirquando disponível)
    • Ele faz o trabalho pesado recorrendo a subpastas


  1. [Python]: glob. glob ( nome do caminho, *, recursivo = Falso ) ( [Python]: glob. iglob ( nome do caminho, *, recursivo = Falso ) )

    Retorna uma lista possivelmente vazia de nomes de caminho que correspondem ao nome do caminho , que deve ser uma string contendo uma especificação de caminho. O nome do caminho pode ser absoluto (como /usr/src/Python-1.5/Makefile) ou relativo (como ../../Tools/*/*.gif) e pode conter curingas no estilo do shell. Links simbólicos quebrados são incluídos nos resultados (como no shell).
    ...
    Alterado na versão 3.5 : Suporte para globs recursivas usando “**”.


    >>> import glob, os
    >>> wildcard_pattern = "*"
    >>> root_dir = os.path.join("root_dir", wildcard_pattern)  # Match every file/dir name
    >>> root_dir
    'root_dir\\*'
    >>>
    >>> glob_list = glob.glob(root_dir)
    >>> glob_list
    ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1']
    >>>
    >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list]  # Strip the dir name and the path separator from begining
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> for entry in glob.iglob(root_dir + "*", recursive=True):
    ...     print(entry)
    ...
    root_dir\
    root_dir\dir0
    root_dir\dir0\dir00
    root_dir\dir0\dir00\dir000
    root_dir\dir0\dir00\dir000\file0000
    root_dir\dir0\dir00\file000
    root_dir\dir0\dir01
    root_dir\dir0\dir01\file010
    root_dir\dir0\dir01\file011
    root_dir\dir0\dir02
    root_dir\dir0\dir02\dir020
    root_dir\dir0\dir02\dir020\dir0200
    root_dir\dir1
    root_dir\dir1\file10
    root_dir\dir1\file11
    root_dir\dir1\file12
    root_dir\dir2
    root_dir\dir2\dir20
    root_dir\dir2\dir20\file200
    root_dir\dir2\file20
    root_dir\dir3
    root_dir\file0
    root_dir\file1
    

    Notas :

    • Usos os.listdir
    • Para árvores grandes (especialmente se recursiveestiver ligado), iglobé preferível
    • Permite a filtragem avançada com base no nome (devido ao curinga)


  1. [Python]: classe pathlib. Caminho ( * pathsegments ) ( !!! Python 3 + !!! não sei se backported)

    >>> import pathlib
    >>> root_dir = "root_dir"
    >>> root_dir_instance = pathlib.Path(root_dir)
    >>> root_dir_instance
    WindowsPath('root_dir')
    >>> root_dir_instance.name
    'root_dir'
    >>> root_dir_instance.is_dir()
    True
    >>>
    >>> [item.name for item in root_dir_instance.glob("*")]  # Wildcard searching for all direct descendants
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()]  # Display paths (including parent) for files only
    ['root_dir\\file0', 'root_dir\\file1']
    

    Notas :

    • Esta é uma maneira de alcançar nosso objetivo
    • É o estilo OOP de lidar com caminhos
    • Oferece muitas funcionalidades


  1. [Python]: dircache.listdir (path) ( !!! removido no Python 3 !!! )

    • Mas, de acordo com $ {PYTHON_SRC_DIR} /Lib/dircache.py : ~ # 20 + (da v2.7.14 ), é apenas um invólucro (fino)os.listdir


    def listdir(path):
        """List directory contents, using cache."""
        try:
            cached_mtime, list = cache[path]
            del cache[path]
        except KeyError:
            cached_mtime, list = -1, []
        mtime = os.stat(path).st_mtime
        if mtime != cached_mtime:
            list = os.listdir(path)
            list.sort()
        cache[path] = mtime, list
        return list
    


  1. [man]: OPENDIR (3) / [man]: READDIR (3) / [man]: CLOSEDIR (3) via [Python]: ctypes - Uma biblioteca de funções externas para Python ( !!! Ux specific !!! )

    ctypes é uma biblioteca de funções estrangeiras para Python. Ele fornece tipos de dados compatíveis com C e permite chamar funções em DLLs ou bibliotecas compartilhadas. Ele pode ser usado para agrupar essas bibliotecas em Python puro.

    code_ctypes.py :

    #!/usr/bin/env python3
    
    import sys
    from ctypes import Structure, \
        c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \
        CDLL, POINTER, \
        create_string_buffer, get_errno, set_errno, cast, sizeof
    
    
    DT_DIR = 4
    DT_REG = 8
    
    char256 = c_char * 256
    
    class LinuxDirent64(Structure):
        _fields_ = [
            ("d_ino", c_ulonglong),
            ("d_off", c_longlong),
            ("d_reclen", c_ushort),
            ("d_type", c_ubyte),
            ("d_name", char256),
        ]
    
    LinuxDirent64Ptr = POINTER(LinuxDirent64)
    
    libc_dll = CDLL(None)
    opendir = libc_dll.opendir
    readdir = libc_dll.readdir
    closedir = libc_dll.closedir
    libc_dll.__errno_location.restype = POINTER(c_int)
    errno_loc_func = libc_dll.__errno_location
    
    
    def _get_errno():
        return "errno: {:d}({:d})".format(get_errno(), errno_loc_func().contents.value)
    
    
    def get_dir_content(path):
        ret = [path, list(), list()]
        dir_stream = opendir(create_string_buffer(path.encode()))
        if (dir_stream == 0):
            print("opendir returned NULL ({:s})".format(_get_errno()))
            return ret
        set_errno(0)
        dirent_addr = readdir(dir_stream)
        while dirent_addr:
            dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr)
            dirent = dirent_ptr.contents
            name = dirent.d_name.decode()
            if dirent.d_type & DT_DIR:
                if name not in (".", ".."):
                    ret[1].append(name)
            elif dirent.d_type & DT_REG:
                ret[2].append(name)
            dirent_addr = readdir(dir_stream)
        if get_errno() or errno_loc_func().contents.value:
            print("readdir returned NULL ({:s})".format(_get_errno()))
        closedir(dir_stream)
        return ret
    
    
    def main():
        print("{:s} on {:s}\n".format(sys.version, sys.platform))
        root_dir = "root_dir"
        entries = get_dir_content(root_dir)
        print(entries)
    
    
    if __name__ == "__main__":
        main()
    

    Notas :

    • Ele carrega as três funções da libc (carregadas no processo atual) e as chama (para mais detalhes confira []: Como eu verifico se existe um arquivo usando Python? (@ Resposta do CristiFati) - últimas notas do item # 4 . ). Isso colocaria essa abordagem muito próxima da borda Python / C
    • LinuxDirent64é a ctypes representação struct dirent64de dirent.h (assim são as DT_*constantes) da minha máquina: Ubtu 16 x64 ( 4.10.0-40-genérico e libc6-dev: amd64 ). Em outros sabores / versões, a definição da estrutura pode ser diferente e, se for o caso, o alias ctypes deve ser atualizado; caso contrário, produzirá um comportamento indefinido.
    • errno_loc_func(e tudo relacionado a isso) é porque o funcs definido errnoem caso de erro, e eu preciso verificar o seu valor. Aparentemente, get_errnonão funciona (com um nome inválido, opendirretorna NULL, mas get_errnoainda retorna 0), ou eu ainda não descobri
    • Ele retorna dados no os.walkformato do. Eu não me incomodei em torná-lo recursivo, mas a partir do código existente, isso seria uma tarefa bastante trivial
    • Tudo é factível no Win também, os dados (bibliotecas, funções, estruturas, constantes, ...) diferem


    Saída :

    [email protected]:~/work//q003207219$ ./code_ctypes.py
    3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    
    ['root_dir', ['dir3', 'dir2', 'dir0', 'dir1'], ['file0', 'file1']]
    


  1. [ActiveState]: win32file.FindFilesW ( !!! Específico do Win !!! )

    Recupera uma lista de nomes de arquivos correspondentes, usando a API do Windows Unicode. Uma interface para a API FindFirstFileW / FindNextFileW / Localizar funções de fechamento.


    >>> import os, win32file, win32con
    >>> root_dir = "root_dir"
    >>> wildcard = "*"
    >>> root_dir_wildcard = os.path.join(root_dir, wildcard)
    >>> entry_list = win32file.FindFilesW(root_dir_wildcard)
    >>> len(entry_list)  # Don't display the whole content as it's too long
    8
    >>> [entry[-2] for entry in entry_list]  # Only display the entry names
    ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")]  # Filter entries and only display dir names (except self and parent)
    ['dir0', 'dir1', 'dir2', 'dir3']
    >>>
    >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)]  # Only display file "full" names
    ['root_dir\\file0', 'root_dir\\file1']
    

    Notas :


  1. Instale algum pacote de terceiros que faça o truque
    • Muito provavelmente, contará com uma (ou mais) das opções acima (talvez com pequenas personalizações)


Notas (sobre as coisas acima):

  • O código destina-se a ser portátil (exceto em locais que segmentam uma área específica - marcada) ou em cruz:
    • plataforma ( Ux , Win )
    • Versão em Python (2, 3,)
  • Estilos de caminho múltiplo (absoluto, parentes) foram usados ​​nas variantes acima, para ilustrar o fato de que as "ferramentas" usadas são flexíveis nessa direção
  • os.listdire os.scandiruse opendir/ readdir/ closedir( [MSDN]: função FindFirstFile / [MSDN]: função FindNextFile / [MSDN]: função FindClose ) (via " $ {PYTHON_SRC_DIR} /Modules/posixmodule.c ")
  • win32file.FindFilesWusa essas funções ( específicas do Win ) também (via " $ {PYWIN32_SRC_DIR} /win32/src/win32file.i ")
  • get_dir_content(do ponto 1 ) podem ser implementadas usando qualquer uma dessas abordagens (algumas exigirão mais trabalho e outras menos)
    • Alguma filtragem avançada (em vez de apenas file vs. dir) poderia ser feita: por exemplo, o include_foldersargumento poderia ser substituído por outro (por exemplo filter_func) que seria uma função que toma um caminho como um argumento: filter_func=lambda x: True(isso não tira nada) e dentro de get_dir_contentalgo como: if not filter_func(entry_with_path): continue(se a função falhar por uma entrada, ela será ignorada), mas quanto mais complexo o código se torna, mais tempo levará para executar
  • Nota bene! Como a recursão é usada, devo mencionar que fiz alguns testes no meu laptop ( Win 10 x64 ), totalmente não relacionados a esse problema e quando o nível de recursão estava atingindo valores em algum lugar no intervalo ( 990 .. 1000) ( recursionlimit - 1000 (padrão)), eu tenho :). Se a árvore de diretórios exceder esse limite (não sou especialista em FS , não sei se isso é possível), isso pode ser um problema.
    Também devo mencionar que não tentei aumentar o recursionlimit porque não tenho experiência na área (quanto posso aumentá-lo antes de ter que aumentar também a pilha no SOnível), mas, em teoria, sempre haverá a possibilidade de falha, se a profundidade dir for maior que o recursionlimit mais alto possível (nessa máquina)
  • As amostras de código são apenas para fins demonstrativos. Isso significa que eu não levar em conta o tratamento de erros (eu não acho que haja qualquer try/ except/ else/ finallybloco), para que o código não é robusta (a razão é: mantê-lo o mais simples e mais curto possível). Para produção , o tratamento de erros também deve ser adicionado

Fim da primeira parte 1


1. Devido ao fato de que o limite da postagem (pergunta / resposta) do Home é de 30000 caracteres ( [SE.Meta]: Conhecendo seus limites: Qual é o tamanho máximo do título da pergunta, postagem, imagem e links usados? ), a resposta foi dividida em duas partes. Por favor, visite [SO]: Como faço para listar todos os arquivos de um diretório? (@ Resposta de CristiFati - "Parte Dois") .


Eu prefiro usar o módulo glob , pois ele faz correspondência e expansão de padrões.

import glob
print(glob.glob("/home/adam/*.txt"))

Ele retornará uma lista com os arquivos consultados:

['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]

Eu realmente gostei da resposta do Adam , sugerindo que você use glob() , do módulo de mesmo nome. Isso permite que você tenha correspondência de padrões com * s.

Mas, como outras pessoas apontaram nos comentários, glob() pode ser tropeçado em direções de barra inconsistentes. Para ajudar com isso, sugiro que você use as funções join() e expanduser() no módulo os.path e, talvez, também a função getcwd() no módulo os .

Como exemplos:

from glob import glob

# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')

O acima é terrível - o caminho foi codificado e só funcionará no Windows entre o nome da unidade e o código codificado no caminho.

from glob    import glob
from os.path import join

# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))

O acima funciona melhor, mas depende do nome da pasta Users que é freqüentemente encontrado no Windows e não tão freqüentemente encontrado em outros sistemas operacionais. Também depende do usuário ter um nome específico, admin .

from glob    import glob
from os.path import expanduser, join

# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))

Isso funciona perfeitamente em todas as plataformas.

Outro ótimo exemplo que funciona perfeitamente entre plataformas e faz algo um pouco diferente:

from glob    import glob
from os      import getcwd
from os.path import join

# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))

Espero que esses exemplos ajudem você a ver o poder de algumas das funções que você pode encontrar nos módulos padrão da biblioteca Python.


Você deve usar o módulo os para listar o conteúdo do diretório. os.listdir(".") retorna todo o conteúdo do diretório. Nós iteramos sobre o resultado e acrescentamos à lista.

import os

content_list = []

for content in os.listdir("."): # "." means current directory
    content_list.append(content)

print content_list

os.listdir() vai te dar tudo o que está em um diretório - arquivos e diretórios.

Se você quiser apenas arquivos, você pode filtrar isso usando os.path :

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

ou você poderia usar os.walk() que irá gerar duas listas para cada diretório que ele visita - dividindo em arquivos e diretórios para você. Se você quer apenas o diretório principal, você pode apenas quebrar a primeira vez que ele render

from os import walk

f = []
for (dirpath, dirnames, filenames) in walk(mypath):
    f.extend(filenames)
    break

E, por último, como mostra esse exemplo, adicionando uma lista a outra, você pode usar .extend() ou

>>> q = [1, 2, 3]
>>> w = [4, 5, 6]
>>> q = q + w
>>> q
[1, 2, 3, 4, 5, 6]

Pessoalmente, eu prefiro .extend()


Retornando uma lista de caminhos de arquivos absolutos, não recorre a subdiretórios

L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]

Execute findfiles () com um diretório como parâmetro e ele retornará uma lista de todos os arquivos contidos nele.

import sys
import os
from pathlib import Path
from glob import glob
platformtype = sys.platform
if platformtype == 'win32':
    slash = "\\"
if platformtype == 'darwin':
    slash = "/"

# TODO: How can I list all files of a directory in Python and add them to a list?

# Step 1 - List all files of a directory

# Method 1: Find only pre-defined filetypes (.txt) and no subfiles, answer provided by @adamk
dir1 = "%sfoo%sbar%s*.txt" % (slash)
_files = glob(dir1)

# Method 2: Find all files and no subfiles
dir2 = "%sfoo%sbar%s" % (slash)
_files = (x for x in Path("dir2").iterdir() if x.is_file())

# Method 3: Find all files and all subfiles
dir3 = "%sfoo%sbar" % (slash)
_files = (x for x in Path('dir3').glob('**/*') if x.is_file())


# Step 2 - Add them to a list

files_list = []
for eachfiles in _files:
    files_basename = os.path.basename(eachfiles)
    files_list.append(files_basename)

Outra variante muito legível para o Python 3.4+ é usando pathlib.Path.glob:

print(files_list)
['file1.txt', 'file2.txt', .... ]

É simples tornar mais específico, por exemplo, apenas procurar por arquivos fonte Python que não sejam links simbólicos, também em todos os subdiretórios:

import os
[f for f in os.listdir(os.getcwd) if ...]

Usando geradores

# python 2.x
import scandir
import sys

de = scandir.scandir(sys.argv[1])
while 1:
    try:
        d = de.next()
        print d.path
    except StopIteration as _:
        break

Aqui está a minha função de propósito geral para isso. Ele retorna uma lista de caminhos de arquivos em vez de nomes de arquivos, pois descobri que isso é mais útil. Tem alguns argumentos opcionais que o tornam versátil. Por exemplo, eu costumo usá-lo com argumentos como pattern='*.txt'ou subfolders=True.

(py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")"
dir0
dir1
dir2
dir3
file0
file1

Estou assumindo que todos os seus arquivos são de *.txtformato e armazenados em um diretório com caminho data/.

Pode-se usar o módulo glob de pythonpara listar todos os arquivos do diretório e adicioná-los a uma lista denominada fnames, da seguinte maneira:

import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
  if len(list[i]) != check:
     temp.append(list[i-1])
     check = len(list[i])
  else:
    i = i + 1
    count = count - 1

print temp

O Python 3.5 introduziu um método novo e mais rápido para percorrer o diretório - os.scandir().

Exemplo:

for file in os.scandir('/usr/bin'):
    line = ''
    if file.is_file():
        line += 'f'
    elif file.is_dir():
        line += 'd'
    elif file.is_symlink():
        line += 'l'
    line += '\t'
    print("{}{}".format(line, file.name))

Referindo-se à resposta de @adamk, aqui está o meu método de detecção do sistema operacional em resposta ao comentário de inconsistência de barra por @Anti Earth

from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]
[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

Estou supondo que você queira apenas os nomes basenames na lista.

Consulte este post para predefinir vários formatos de arquivo para o Método 1.


Se você se preocupa com o desempenho, tente scandir. Para o Python 2.x, talvez seja necessário instalá-lo manualmente. Exemplos:

def scan_path(path):
    de = scandir.scandir(path)
    while 1:
        try:
            e = de.next()
            if e.is_dir():
                scan_path(e.path)
            else:
                print e.path
        except StopIteration as _:
                break

Isso economiza muito tempo quando você precisa digitalizar um diretório enorme, e você não precisa armazenar em buffer uma lista enorme, basta buscar um por um. E também você pode fazer isso de forma recursiva:

import os

def createList(foldername, fulldir = True, suffix=".jpg"):
    file_list_tmp = os.listdir(foldername)
    #print len(file_list_tmp)
    file_list = []
    if fulldir:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(os.path.join(foldername, item))
    else:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(item)
    return file_list

Usando a osbiblioteca.

import os
def findfiles(directory):
    objects = os.listdir(directory)  # find all objects in a dir

    files = []
    for i in objects:  # check if very object in the folder ...
        if os.path.isfile(os.path.join(directory, i)):  # ... is a file.
            files.append(i)  # if yes, append it.
    return files

def list_files(path):
    # returns a list of names (with extension, without full path) of all files 
    # in folder path
    files = []
    for name in os.listdir(path):
        if os.path.isfile(os.path.join(path, name)):
            files.append(name)
    return files 

filenames = next(os.walk(path))[2]

Isso retornará uma lista de todos os arquivos e diretórios no path.

import os
for root, dirs,files in os.walk("your dir path", topdown=True):
    for name in files:
        print(os.path.join(root, name))

Isso retornará apenas uma lista de arquivos, não subdiretórios.


import os
import os.path


def get_files(target_dir):
    item_list = os.listdir(target_dir)

    file_list = list()
    for item in item_list:
        item_dir = os.path.join(target_dir,item)
        if os.path.isdir(item_dir):
            file_list += get_files(item_dir)
        else:
            file_list.append(item_dir)
    return file_list

Aqui eu uso uma estrutura recursiva.


import os
lst=os.listdir(path)

os.listdir retorna uma lista contendo os nomes das entradas no diretório fornecido pelo caminho.







directory