Estou trabalhando em um script para percorrer recursivamente as subpastas em uma pasta principal e construir uma lista de um determinado tipo de arquivo. Estou tendo um problema com o script. Atualmente está definido como segue
for root, subFolder, files in os.walk(PATH):
for item in files:
if item.endswith(".txt") :
fileNamePath = str(os.path.join(root,subFolder,item))
o problema é que a variável subFolder está obtendo uma lista de subpastas em vez da pasta em que o arquivo ITEM está localizado. Eu estava pensando em executar um loop for para a subpasta antes e juntar a primeira parte do caminho, mas achei que deveria verificar se alguém tem alguma sugestão antes disso. Obrigado pela ajuda!
rglob
é insensível em plataformas Windows - mas não é insensível a portabilidade.glob
também (Python 3.6 aqui):glob.iglob(os.path.join(real_source_path, '**', '*.[xX][mM][lL]')
iglob
não funciona para arquivos em sub-subpastas ou abaixo. Você precisa adicionarrecursive=True
.glob.glob()
tem um novo parâmetro recursivo .Se você deseja obter todos os
.txt
arquivos sobmy_path
(recursivamente incluindo subdiretórios):Se precisar de um iterador, você pode usar o iglob como alternativa:
fonte
files = glob.glob(PATH + '/*/**/*.txt', recursive=True)
?Vou traduzir a compreensão da lista de John La Rooy em for's aninhados, apenas no caso de alguém ter problemas para entendê-la.
Deve ser equivalente a:
Aqui está a documentação para compreensão de listas e as funções os.walk e glob.glob .
fonte
glob.glob(..., recursive=True)
elist(Path(dir).glob(...'))
não o fez.Esta parece ser a solução mais rápida que eu poderia vir acima com, e é mais rápido do que
os.walk
e muito mais rápido do que qualquerglob
solução .f.path
paraf.name
(não altere para as subpastas!).Args:
dir: str, ext: list
.Função retorna duas listas:
subfolders, files
.Veja abaixo uma análise detalhada da velocidade.
Análise rápida
para vários métodos de obter todos os arquivos com uma extensão de arquivo específica dentro de todas as subpastas e da pasta principal.
tl; dr:
-
fast_scandir
claramente vence e é duas vezes mais rápido que todas as outras soluções, exceto os.walk.-
os.walk
é o segundo lugar ligeiramente mais lento.- o uso
glob
tornará o processo muito mais lento.- Nenhum dos resultados usa classificação natural . Isso significa que os resultados serão classificados como: 1, 10, 2. Para obter uma classificação natural (1, 2, 10), dê uma olhada em https://stackoverflow.com/a/48030307/2441026
Resultados:
Os testes foram feitos com W7x64, Python 3.8.1, 20 execuções. 16.596 arquivos em 439 subpastas (parcialmente aninhadas).
find_files
vem de https://stackoverflow.com/a/45646357/2441026 e permite que você pesquise várias extensões.fast_scandir
foi escrito por mim e também retornará uma lista de subpastas. Você pode fornecer uma lista de extensões para pesquisar (eu testei uma lista com uma entrada para uma simplesif ... == ".jpg"
e não houve diferença significativa).fonte
A nova
pathlib
biblioteca simplifica isso para uma linha:Você também pode usar a versão do gerador:
Isso retorna
Path
objetos, que você pode usar para praticamente qualquer coisa, ou obter o nome do arquivo como uma string porfile.name
.fonte
Não é a resposta mais pitônica, mas vou colocá-la aqui para me divertir porque é uma boa lição de recursão
Na minha máquina, tenho duas pastas
root
eroot2
Digamos que eu queira encontrar todos
.txt
os.mid
arquivos em qualquer um desses diretórios, então posso apenas fazerfonte
Recursivo é novo no Python 3.5, então não funcionará no Python 2.7. Aqui está o exemplo que usa
r
strings, portanto, você só precisa fornecer o caminho como está em Win, Lin, ...Observação: ele listará todos os arquivos, não importa a profundidade que deva ir.
fonte
Você pode fazer isso desta forma para retornar uma lista de arquivos de caminho absoluto.
fonte
Se você não se importar em instalar uma biblioteca de luz adicional, pode fazer o seguinte:
Uso:
O resultado deve ser semelhante a este:
Funciona tanto no Python 2.7 quanto no Python 3.
Github: https://github.com/kyzas/plazy#list-files
Isenção de responsabilidade: eu sou um autor de
plazy
.fonte
Esta função irá colocar recursivamente apenas arquivos em uma lista. Espero que este seja você.
fonte
Sua solução original estava quase correta, mas a variável "root" é atualizada dinamicamente à medida que se movimenta recursivamente. os.walk () é um gerador recursivo. Cada conjunto de tupla de (raiz, subpasta, arquivos) é para uma raiz específica da maneira como você a configurou.
ie
Fiz um pequeno ajuste no seu código para imprimir uma lista completa.
Espero que isto ajude!
fonte