2010-02-03 12 views
10

Estoy escribiendo una secuencia de comandos de Python que va a través de un directorio y reúne ciertos archivos, pero hay una cantidad de archivos que quiero excluir y todos comienzan de la misma manera.En python, ¿cómo excluyo archivos de un ciclo si comienzan con un conjunto específico de letras?

código Ejemplo:

for name in files: 
    if name != "doc1.html" and name != "doc2.html" and name != "doc3.html": 
     print name 

Digamos que hay 100 centenar de archivos HTML en el directorio de todos los que comienzan con 'doc'. ¿Cuál sería la forma más fácil de excluirlos?

Lo siento, soy nuevo en Python, sé que esto es probablemente básico.

Gracias de antemano.

+3

A veces simplemente me elude: cómo y por qué tales preguntas obtienen 4 votos positivos. Además de ser un imbécil de http://stackoverflow.com/questions/1176441/how-to-filter-files-with-known-type-from-os-walk y algunas otras preguntas, es absolutamente trivial y muestra un básico falta de conocimiento de las herramientas que proporciona el lenguaje –

+5

@Eli: ¿Estás diciendo que debemos ignorar las preguntas triviales y básicas? El hecho de que algo sea trivial y básico para usted no significa que no sea complejo y nuevo para otra persona. –

+0

Gracias Daniel, básicamente necesitaba una solución rápida, y llegué al lugar correcto porque tenía la solución en menos de un minuto. – Ruth

Respuesta

20
if not name.startswith('doc'): 
    print name 

Si usted tiene más prefijos para excluir incluso se puede hacer esto:

if not name.startswith(('prefix', 'another', 'yetanother')): 
    print name 

startswith puede aceptar una tupla de prefijos.

5
for name in files: 
    if not name.startswith("doc"): 
     print name 
+0

Lo que estoy buscando sería lo opuesto a startswith, si hubiera un método llamado doesnotstartwith(), sería ordenado :) – Ruth

+1

@Ruth: no es verdad == Falso – telliott99

+0

lo siento, no sé cómo me perdí – Ruth

0
for name in files: 
    if name[0:3] == "doc": 
     continue 
0

Si todos ellos comienzan igual (es decir, con "doc"), podría utilizar el método startswith() de la cadena de Python.

for name in files: 
    if not name.startswith("doc"): 
     print name 
0

Dado que usted no dijo si hay buenas archivos que empiezan por 'Doc' y termina con '.html' que tendrá que declarar una set de malos nombres de archivo y proceso sólo no los archivos en ese conjunto.

bad_files = set(["doc1.html", "doc2.html", "doc3.html"]) 

for file in files: 
    if file not in bad_files: 
    print file 

Si necesita cambiar dinámicamente la lista de nombres de ficheros utilizan un list.

+0

eso bueno también, gracias – Ruth

+1

Al menos use un conjunto en lugar de una lista. la búsqueda de conjunto es O (1), la búsqueda de lista es O (N). –

+0

@Nadia Alramli cambió al ejemplo como sugirió –

1
import os 
os.chdir("/home") 
for file in os.listdir("."): 
    if os.path.isfile(file) and not file.startswith("doc"): 
     print file 
3

Si encuentra la programación funcional coincide con su estilo mejor, Python hace que sea sencillo para filtrar las listas con el filtro() Función:

>>> files = ["doc1.html", "doc2.html", "doc3.html", "index.html", "image.jpeg"] 
>>> filter_function = lambda name: not name.startswith("doc") 
>>> filter(filter_function, files) 
['index.html', 'image.jpeg'] 

también echar un vistazo a aplicar(), del mapa() , reduce() y zip().

+0

Pero tenga en cuenta que 'apply()' ha quedado en desuso desde 2.3: http: //docs.python .org/library/functions.html # apply –

1

se parece a este problema podría ser una mejor opción para la materia de la lista así como Troy dijo (Aunque prefiero poner la función directamente en el filtro)

filter(lambda filename: not filename.startswith("doc"),files) 

o

[filename for filename in files if not filename.startswith("doc")] 
1

Usted podría también use un list comprehension.

cleaned_list = [filename for filename in files if not filename.startswith('doc')] 
0

Una toma alternativa a una solución funcional a este problema, con la ventaja de usar adiciones recientes a la biblioteca estándar (usando el mismo ejemplo nombres de archivo como Troy J.Farrell en otra respuesta):

>>> import operator, itertools 
>>> filter_fun= operator.methodcaller("startswith", "doc") 
>>> files = ["doc1.html", "doc2.html", "doc3.html", "index.html", "image.jpeg"] 
>>> list(itertools.ifilterfalse(filter_fun, files)) 
['index.html', 'image.jpeg'] 

operator.methodcaller llamada con methodname, [optional arguments] devuelve una función que, cuando se le llama con un objeto obj como su argumento, devuelve el resultado de obj.methodname(optional_arguments). itertools.ifilterfalse, a diferencia de filter, devuelve un iterador en lugar de una lista y la decisión de filtro es negada.

0

Estos son mis 2 centavos:
Un poco de comprensión en la lista. Siempre es mejor para la eficiencia.

file_list = [file for file in directory if not file.startswith(("name1", "name2", "name3"))] 
Cuestiones relacionadas