¿Cómo puedo iterar sobre archivos en un directorio dado?


556

Necesito iterar a través de todos los .asmarchivos dentro de un directorio dado y hacer algunas acciones en ellos.

¿Cómo se puede hacer esto de manera eficiente?

Respuestas:


808

Respuesta original:

import os

for filename in os.listdir(directory):
    if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
        continue
    else:
        continue

Versión de Python 3.6 de la respuesta anterior, usando os- asumiendo que tiene la ruta del directorio como un strobjeto en una variable llamada directory_in_str:

import os

directory = os.fsencode(directory_in_str)

for file in os.listdir(directory):
     filename = os.fsdecode(file)
     if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
         continue
     else:
         continue

O recursivamente, usando pathlib:

from pathlib import Path

pathlist = Path(directory_in_str).glob('**/*.asm')
for path in pathlist:
     # because path is object not string
     path_in_str = str(path)
     # print(path_in_str)

1
Esto simplemente parece enumerar los directorios o archivos inmediatamente debajo de un directorio. La respuesta de pedromateo a continuación parece hacer una lista recursiva.
Jay Sheth

8
Tenga en cuenta que en Python 3.6 se espera que el directorio esté en bytes y luego listdir escupirá una lista de nombres de archivo también en el tipo de datos de bytes, por lo que no puede ejecutar extremos directamente en él. Este bloque de código debe cambiarse adirectory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
Kim Stacks,

13
print(os.path.join(directory, filename))necesita ser cambiado para print(os.path.join(directory_in_str, filename))que funcione en Python 3.6
Hugo Koopmans

54
Si está viendo esto en 2017 o más allá, os.scandir (dir_str) ahora está disponible y es mucho más limpio de usar. No hay necesidad de fsencode. for entry in os.scandir(path): print(entry.path)
cabra

2
Prefiero if filename.endswith((".asm", ".py")):aif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio

153

Esto iterará sobre todos los archivos descendientes, no solo los hijos inmediatos del directorio:

import os

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        #print os.path.join(subdir, file)
        filepath = subdir + os.sep + file

        if filepath.endswith(".asm"):
            print (filepath)

3
Una referencia para la función os.walk se encuentra en lo siguiente: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC

136

Puedes intentar usar el módulo glob :

import glob

for filepath in glob.iglob('my_dir/*.asm'):
    print(filepath)

y desde Python 3.5 también puedes buscar subdirectorios:

glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']

De los documentos:

El módulo glob encuentra todos los nombres de ruta que coinciden con un patrón especificado de acuerdo con las reglas utilizadas por el shell de Unix, aunque los resultados se devuelven en orden arbitrario. No se realiza la expansión de tilde, pero *,? Y los rangos de caracteres expresados ​​con [] coincidirán correctamente.


19

Desde Python 3.5, las cosas son mucho más fáciles con os.scandir ( )

with os.scandir(path) as it:
    for entry in it:
        if entry.name.endswith(".asm") and entry.is_file():
            print(entry.name, entry.path)

El uso de scandir () en lugar de listdir () puede aumentar significativamente el rendimiento del código que también necesita información de tipo de archivo o atributo de archivo, porque los objetos os.DirEntry exponen esta información si el sistema operativo la proporciona al escanear un directorio. Todos los métodos os.DirEntry pueden realizar una llamada al sistema, pero is_dir () y is_file () generalmente solo requieren una llamada al sistema para enlaces simbólicos; os.DirEntry.stat () siempre requiere una llamada al sistema en Unix, pero solo requiere una para enlaces simbólicos en Windows.


entryes un posix.DirEntry tipo con un montón de métodos útiles como entry.is_dir(), is_file(),is_symlink()
crypdick

17

Python 3.4 y posterior ofrecen pathlib en la biblioteca estándar. Podrías hacerlo:

from pathlib import Path

asm_pths = [pth for pth in Path.cwd().iterdir()
            if pth.suffix == '.asm']

O si no te gustan las comprensiones de listas:

asm_paths = []
for pth in Path.cwd().iterdir():
    if pth.suffix == '.asm':
        asm_pths.append(pth)

Path Los objetos se pueden convertir fácilmente en cadenas.


9

Así es como itero a través de archivos en Python:

import os

path = 'the/name/of/your/path'

folder = os.fsencode(path)

filenames = []

for file in os.listdir(folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
        filenames.append(filename)

filenames.sort() # now you have the filenames and can do something with them

NINGUNA DE ESTAS TÉCNICAS GARANTIZAN CUALQUIER ORDEN DE ITERACIÓN

Sí, súper impredecible. Tenga en cuenta que clasifico los nombres de archivo, lo cual es importante si el orden de los archivos es importante, es decir, para cuadros de video o recolección de datos dependiente del tiempo. ¡Sin embargo, asegúrese de poner índices en sus nombres de archivo!


No siempre ordenado ... im1, im10, im11 ..., im2 ... De lo contrario, enfoque útil. from pkg_resources import parse_versiony lo filenames.sort(key=parse_version)hice
Hastur

5

Puede usar glob para referir el directorio y la lista:

import glob
import os

#to get the current working directory name
cwd = os.getcwd()
#Load the images from images folder.
for f in glob.glob('images\*.jpg'):   
    dir_name = get_dir_name(f)
    image_file_name = dir_name + '.jpg'
    #To print the file name with path (path will be in string)
    print (image_file_name)

Para obtener la lista de todos los directorios en la matriz, puede usar os :

os.listdir(directory)

4

Todavía no estoy muy contento con esta implementación, quería tener un constructor personalizado que lo haga de DirectoryIndex._make(next(os.walk(input_path)))tal manera que pueda pasar la ruta para la que desea una lista de archivos. Ediciones de bienvenida!

import collections
import os

DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])

for file_name in DirectoryIndex(*next(os.walk('.'))).files:
    file_path = os.path.join(path, file_name)

2

Realmente me gusta usar la scandirdirectiva que está integrada en la osbiblioteca. Aquí hay un ejemplo de trabajo:

import os

i = 0
with os.scandir('/usr/local/bin') as root_dir:
    for path in root_dir:
        if path.is_file():
            i += 1
            print(f"Full path is: {path} and just the name is: {path.name}")
print(f"{i} files scanned successfully.")

respuesta duplicada
crypdick
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.