Necesito iterar a través de todos los archivos .asm dentro de un directorio determinado y realizar algunas acciones en ellos.
¿Cómo se puede hacer esto de una manera eficiente?
Desde Python 3.5, las cosas son mucho más fáciles con os.scandir( ) y 2-20 veces más rápido ( fuente ):
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 sobre el tipo de archivo o el atributo del 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() e 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.
Realmente me gusta usar la directiva scandir que está integrada en la biblioteca os . 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.")Puedes 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)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 themNINGUNA DE ESTAS TÉCNICAS GARANTIZA NINGÚN ORDEN DE ITERACIÓN
Sí, súper impredecible. Tenga en cuenta que ordeno los nombres de los archivos, lo cual es importante si el orden de los archivos importa, es decir, para cuadros de video o recopilación de datos dependiente del tiempo. ¡Sin embargo, asegúrese de poner índices en sus nombres de archivo!
Python 3.4 y versiones posteriores 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 listas de comprensión:
asm_paths = [] for pth in Path.cwd().iterdir(): if pth.suffix == '.asm': asm_pths.append(pth) Los objetos de Path se pueden convertir fácilmente en cadenas.
Todavía no estoy muy contento con esta implementación, quería tener un constructor personalizado que haga DirectoryIndex._make(next(os.walk(input_path))) de modo que pueda pasar la ruta para la que desea una lista de archivos. ¡Ediciones bienvenidas!
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)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)Versión de Python 3.6 de la respuesta anterior, usando os , suponiendo que tiene la ruta del directorio como un objeto str 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)rglob para reemplazar glob('**/*.asm') con rglob('*.asm')Path.glob() con '**/' agregado delante del patrón relativo dado: from pathlib import Path pathlist = Path(directory_in_str).rglob('*.asm') for path in pathlist: # because path is object not string path_in_str = str(path) # print(path_in_str)Respuesta original:
import os for filename in os.listdir("/path/to/dir/"): if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continuePuedes 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 puede 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 específico de acuerdo con las reglas utilizadas por el shell de Unix, aunque los resultados se devuelven en un orden arbitrario. No se realiza ninguna expansión de tilde, pero *, ? y los rangos de caracteres expresados con [] coincidirán correctamente.