Contar el número de archivos con cierta extensión en Python


Soy bastante nuevo en Python y estoy tratando de averiguar la forma más eficiente de contar el número de .Archivos TIF en un subdirectorio en particular.

Haciendo algunas búsquedas, encontré un ejemplo (no he probado), que afirmaba contar todos los archivos en un directorio:

file_count = sum((len(f) for _, _, f in os.walk(myPath)))

Esto está bien, pero solo necesito contar archivos TIF. Mi directorio contendrá otros tipos de archivos, pero solo quiero contar TIFs.

Actualmente estoy usando lo siguiente código:

tifCounter = 0
for root, dirs, files in os.walk(myPath):
    for file in files:    
        if file.endswith('.tif'):
            tifCounter += 1

Funciona bien, pero el bucle parece ser excesivo/caro para mí. ¿Hay alguna forma de hacer esto de manera más eficiente?

Gracias.

Author: S.Lott, 2009-08-24

5 answers

Algo tiene que iterar sobre todos los archivos en el directorio, y mirar cada nombre de archivo, ya sea su código o una rutina de biblioteca. Así que no importa cuál sea la solución específica, todos tendrán aproximadamente el mismo costo.

Si crees que es demasiado código, y si realmente no necesitas buscar subdirectorios recursivamente, puedes usar el módulo glob:

tifCounter = len(glob.glob1(myPath,"*.tif"))
 37
Author: Martin v. Löwis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-24 06:26:35

Tu código está bien.

Sí, vas a necesitar hacer un bucle sobre esos archivos para filtrar el .archivos tif, pero el bucle sobre una pequeña matriz en memoria es insignificante en comparación con el trabajo de escanear el directorio de archivos para encontrar estos archivos en primer lugar, lo que tiene que hacer de todos modos.

No me preocuparía por optimizar este código.

 4
Author: Triptych,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-24 06:24:47

Para este caso de uso en particular, si no desea buscar recursivamente en el subdirectorio, puede usar os.listdir:

len([f for f in os.listdir(myPath) 
     if f.endswith('.tif') and os.path.isfile(os.path.join(myPath, f))])
 4
Author: tonfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-24 12:28:23

Si necesitas buscar recursivamente, o por alguna otra razón no quieres usar el módulo glob, puedes usar

file_count = sum(len(f for f in fs if f.lower().endswith('.tif')) for _, _, fs in os.walk(myPath))

Esta es la forma "pitónica" de adaptar el ejemplo que encontraste para tus propósitos. Pero no va a ser significativamente más rápido o más eficiente que el bucle que has estado usando; es solo una sintaxis realmente compacta para más o menos lo mismo.

 2
Author: David Z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-24 06:39:08

Intenta usar fnmatch https://docs.python.org/2/library/fnmatch.html

import fnmatch,os
num_files = len(fnmatch.filter(os.listdir(your_dir),'*.tif'))
print(num_files)
 1
Author: pyBomb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 16:23:03