Estoy escribiendo un script que desciende a un árbol de directorios (usando os.walk ()) y luego visita cada archivo que coincide con una determinada extensión de archivo. Sin embargo, dado que algunos de los árboles de directorios en los que se usará mi herramienta también contienen subdirectorios que a su vez contienen MUCHAS cosas inútiles (para el propósito de este script), pensé que agregaría una opción para que el usuario especifique una lista de directorios para excluir del recorrido.
Esto es bastante fácil con os.walk (). Después de todo, depende de mí decidir si realmente quiero visitar los archivos / directorios respectivos producidos por os.walk () o simplemente omitirlos. El problema es que si tengo, por ejemplo, un árbol de directorios como este:
root--
|
--- dirA
|
--- dirB
|
--- uselessStuff --
|
--- moreJunk
|
--- yetMoreJunk
y quiero excluir a uselessStuff y todos sus elementos secundarios, os.walk () seguirá descendiendo a todos los (potencialmente miles de) subdirectorios de uselessStuff , lo que, no hace falta decirlo, ralentiza mucho las cosas. En un mundo ideal, podría decirle a os.walk () que ni siquiera se moleste en dar más hijos de inútil Stuff , pero que yo sepa, no hay forma de hacerlo (¿existe?).
¿Alguien tiene alguna idea? ¿Tal vez hay una biblioteca de terceros que proporciona algo así?
dirs[:] =
?dirs[:] = value
modificadirs
en el lugar . Cambia el contenido de la listadirs
sin cambiar el contenedor. Como sehelp(os.walk)
menciona, esto es necesario si desea afectar la forma en queos.walk
atraviesa los subdirectorios. (dirs = value
simplemente reasigna (o "vincula") la variabledirs
a una nueva lista, sin modificar el originaldirs
.)filter()
:dirs[:] = list(filter(lambda x: not x in exclude, dirs))
os.walk
y rindaroot, dirs, files
después de excluir.git
(o cualquier otra cosa que desee)dirs
.... una forma alternativa de la excelente respuesta de @unutbu que se lee un poco más directamente, dado que la intención es excluir directorios, a costa de O (n ** 2) vs O (n) tiempo.
(
list(dirs)
Se requiere hacer una copia de la lista de directorios con la ejecución correcta)fuente
dirs[:] = set(dirs) - exclude
. Al menos sigue siendo \ $ O (n) \ $ y no construyes una comprensión solo por sus efectos secundarios ...for d in list(dirs)
es un poco extrañodirs
Ya es una lista. Y lo que tienes no es realmente una lista de comprensión.dirs.remove(d)
no devuelve nada, así que terminas con una lista llena deNone
s. Estoy de acuerdo con @Torsten.