2010-02-03 4 views
10

Sto scrivendo uno script Python che passa attraverso una directory e raccoglie alcuni file, ma ci sono un certo numero di file che voglio escludere che iniziano tutti uguali.In python, come posso escludere i file da un ciclo se iniziano con una serie specifica di lettere?

codice Esempio:

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

Diciamo che ci sono 100 centinaia di file HTML nella directory tutti iniziano con 'doc'. Quale sarebbe il modo più semplice per escluderli?

Scusa se sono nuovo di Python, so che questo è probabilmente di base.

Grazie in anticipo.

+3

A volte mi sfugge semplicemente - come e perché tali domande ottengono 4 upvotes. Oltre ad essere un duplicato di http://stackoverflow.com/questions/1176441/how-to-filter-files-with-known-type-from-os-walk e di altre domande, è assolutamente banale e mostra una base mancanza di conoscenza di quali strumenti fornisce la lingua –

+5

@Eli: Stai dicendo che dovremmo ignorare le domande banali e di base? Solo perché qualcosa è banale e basilare per te non significa che non sia complesso e nuovo per qualcun altro. –

+0

Grazie Daniel, in pratica avevo bisogno di una soluzione rapida, e sono venuto nel posto giusto perché avevo la soluzione in meno di un minuto. – Ruth

risposta

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

Se si dispone di più prefissi per escludere che si può anche fare questo:

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

startswith può accettare una tupla di prefissi.

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

Quello che sto cercando sarebbe il contrario di startswith, se ci fosse un metodo chiamato doesnotstartwith(), sarei ordinato :) – Ruth

+1

@Ruth: non vero == Falso – telliott99

+0

scusa, non so come mi sono perso quel – Ruth

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

Se tutti iniziano lo stesso (cioè con "doc") è possibile utilizzare il metodo startswith() della stringa python.

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

Dal momento che non ha detto se ci sono buone file che iniziano con 'Doc' e termina con '.html' si dovrà dichiarare un set di cattivi nomi di file e di processo non solo i file in quella retata.

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

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

Se avete bisogno di cambiare dinamicamente l'elenco dei nomi di file utilizzare un list.

+0

questo bene anche, grazie – Ruth

+1

Almeno usare un set al posto di una lista. set lookup è O (1), la ricerca lista è O (N). –

+0

@Nadia Alramli è cambiato in un esempio come suggerito –

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

Se trovate la programmazione funzionale corrisponde al tuo stile migliore, Python rende semplice per filtrare le liste con il filtro() la funzione:

>>> 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'] 

prendere anche uno sguardo a applicare(), map() , reduce() e zip().

+0

Ma si noti che 'apply()' è stato deprecato dal 2.3: http: //docs.python .org/library/functions.html # applicano –

1

assomiglia a questo problema potrebbe essere una misura migliore per la roba lista così come Troy ha detto (Anche se io preferisco mettere la funzione direttamente nel filtro)

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

o

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

Si potrebbe utilizzare anche un list comprehension.

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

un take alternativo ad una soluzione funzionale a questo problema, con il vantaggio di utilizzare recenti aggiunte alla libreria standard (usando lo stesso esempio nomi come Troy J.Farrell in un'altra risposta):

>>> 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 chiamato con methodname, [optional arguments] restituisce una funzione che, quando viene chiamato con un oggetto obj come argomento, restituisce il risultato della obj.methodname(optional_arguments). itertools.ifilterfalse, a differenza di filter, restituisce un iteratore anziché un elenco e la decisione sul filtro viene annullata.

0

Questo è il mio 2 cent:
Un po 'di comprensione delle liste. È sempre meglio per l'efficienza.

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