2010-02-03 7 views
10

Piszę skrypt Pythona, który przechodzi przez katalog i gromadzi pewne pliki, ale istnieje wiele plików, które chcę wyłączyć, że wszystkie zaczynają się tak samo.W python, jak mogę wykluczyć pliki z pętli, jeśli zaczynają się od określonego zestawu liter?

Przykładowy kod:

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

Powiedzmy istnieje 100 sto pliki HTML w katalogu wszystko zaczynające 'doc'. Jaki byłby najprostszy sposób na ich wykluczenie?

Przepraszam, że jestem nowy w Pythonie, wiem, że to prawdopodobnie podstawa.

Z góry dziękuję.

+3

Czasami po prostu mnie umyka - jak i dlaczego takie pytania zdobywają 4 przegrane. Oprócz bycia dupkiem http://stackoverflow.com/questions/1176441/how-to-filter-files-with-known-type-from-os-walk i kilkoma innymi pytaniami, jest to absolutnie banalne i pokazuje podstawowe brak świadomości, jakie narzędzia zapewnia język –

+5

@ Eli: Mówisz, że powinniśmy zignorować proste i podstawowe pytania? To, że coś jest dla ciebie banalne i proste, nie oznacza, że ​​nie jest skomplikowane i nowe dla kogoś innego. –

+0

Dziękuję Danielowi, w zasadzie potrzebowałem szybkiej naprawy i trafiłem we właściwe miejsce, ponieważ miałem rozwiązanie w mniej niż minutę. – Ruth

Odpowiedz

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

Jeśli masz więcej prefiksów, aby wykluczyć można nawet to zrobić:

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

startswith może zaakceptować krotki prefiksów.

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

To, czego szukam, byłoby przeciwieństwem startwith, gdyby istniała metoda o nazwie doesnotstartwith(), zostałbym posortowany :) – Ruth

+1

@Ruth: not True == Fałsz – telliott99

+0

Przepraszam, dunno, jak tęskniłem za tym – Ruth

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

Jeśli wszystkie z nich zaczynają się tak samo (tzn. Z "doc"), można użyć metody startswith() łańcucha Pythona.

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

Ponieważ nie powiedzieć, czy istnieją pliki zaczynające się od „doc” i kończące się na „.html” trzeba będzie zadeklarować set złych nazw plików i proces nie tylko w tym zestawie.

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

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

Jeśli chcesz dynamicznie zmieniać listę nazw plików, użyj numeru list.

+0

dobrze też, dzięki – Ruth

+1

Przynajmniej użyj zestawu zamiast listy. wyszukiwanie zestawu to O (1), wyszukiwanie listy to O (N). –

+0

@Nadia Alramli zmieniono na przykład, tak jak zasugerowałeś –

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

Jeśli okaże programowanie funkcjonalne pasuje Twój styl lepiej, Python ułatwia filtrowanie list z filtrem() funkcja:

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

wziąć również spojrzeć na apply(), mapy() , reduce() i zip().

+0

Ale zauważ, że 'apply()' jest przestarzałe od 2.3: http: //docs.python .org/library/functions.html # apply –

1

wygląda ten problem może być lepsze dopasowanie do listy rzeczy tak jak powiedział Troy (Chociaż ja wolę wprowadzenie funkcji bezpośrednio do filtra)

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

lub

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

Mogłabyś używaj także list comprehension.

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

Alternatywny odbioru do funkcjonalne rozwiązanie tego problemu, z korzyścią stosowania ostatnie dodatki do standardowego biblioteki (z wykorzystaniem tego samego przykładu nazw jak J. TroyFarrell w innym odpowiedź):

>>> 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 wywołana methodname, [optional arguments] zwraca funkcję, gdy wywołana z obiektu obj jako argument, zwraca wynik obj.methodname(optional_arguments). itertools.ifilterfalse, w przeciwieństwie do filter, zwraca iterator zamiast listy, a decyzja filtru jest zanegowana.

0

To jest moje 2 centy:
Trochę rozumienia listy. Zawsze jest lepiej dla skuteczności.

file_list = [file for file in directory if not file.startswith(("name1", "name2", "name3"))] 
Powiązane problemy