2009-08-24 17 views
21

Jestem całkiem nowy w Pythonie i staram się znaleźć najbardziej efektywny sposób zliczania plików .TIF w określonym podkatalogu.Liczba plików z pewnym rozszerzeniem w Pythonie

Robi kilka wyszukiwania, znalazłem jeden przykład (nie testowałem), który twierdził, że liczą się wszystkie pliki w katalogu:

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

Jest to dobre rozwiązanie, ale trzeba liczyć tylko pliki TIF . Mój katalog będzie zawierał inne typy plików, ale chcę tylko liczyć TIF-y.

Obecnie używam następujący kod:

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

To działa dobrze, ale pętli wydaje się nadmierna/drogie dla mnie. W jaki sposób można to zrobić bardziej efektywnie?

Dzięki.

+0

najbardziej efektywny sposób, aby robić rzeczy w Pythonie jest często je zrobić w C . :) – Imagist

+3

Co ci się nie podoba w tym temacie? Co oznacza "nadmierny"? Co oznacza "drogi"? –

Odpowiedz

32

Coś musi powtórzyć wszystkie pliki w katalogu i sprawdzić każdą nazwę pliku - niezależnie od tego, czy jest to kod, czy biblioteka. Bez względu na to, jakie konkretne rozwiązanie, wszystkie będą miały mniej więcej ten sam koszt.

Jeśli uważasz, że to zbyt dużo kodu, a jeśli nie faktycznie trzeba szukać podkatalogi rekurencyjnie, można użyć modułu glob:

tifCounter = len(glob.glob1(myPath,"*.tif")) 
+0

Dzięki. To działało równie dobrze, aw 1/5 liczba linii! Nawet jeśli kosztuje to tyle samo, wygląda ładniej! :) –

+0

'glob1'? po co korzystać z nieudokumentowanej funkcji? dlaczego nie użyć "glob.glob", który daje dokładnie taki sam wynik? – SilentGhost

+1

@SilentGhost: glob.glob oczekuje tylko jednego parametru, który jest nazwą ścieżki. W konkretnym przypadku katalog jest już dostępny, więc nie ma potrzeby dołączania go wcześniej, tak aby glob mógł go ponownie rozdzielić. Dodatkowo, jeśli myPath ma postać globalną, glob.glob zinterpretuje to. –

4

Twój kod jest w porządku.

Tak, będziesz musiał przechwycić te pliki, aby odfiltrować pliki .tif, ale pętla nad małą tablicą w pamięci jest pomijalna w porównaniu do pracy skanowania katalogu plików, aby znaleźć te pliki w pierwsze miejsce, które i tak musisz zrobić.

Nie martwię się o optymalizację tego kodu.

2

Jeśli musisz szukać rekursywnie, lub dla niektórych Innym powodem nie chcą korzystać z modułu glob, można użyć

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

jest to „pythonowy” sposób dostosować przykład znalazłeś dla swoich celów. Ale nie będzie to znacznie szybsze ani wydajniejsze niż pętla, z której korzystasz; to po prostu naprawdę kompaktowa składnia mniej więcej to samo.

+4

Od kiedy to określenie "pythonic" opisuje rutynę przekształcania doskonale czytelnych 3 linii kodu w jedną linię zagnieżdżonych pętli, która zajmuje co najmniej 5 razy więcej czasu, aby zrozumieć i narusza PEP8 w procesie? –

+0

Ponieważ ludzie robili tego rodzaju rzeczy w Pythonie (i to było dość długo). Ale zauważ, że umieszczam "Pythonica" w cudzysłowie ("quote-Pythonic-unquote"), ponieważ to, co faktycznie robi się w Pythonie, a co jest określone w PEP 8 to dwie różne rzeczy. –

4

W tym konkretnym przypadku, jeśli nie chce rekursywnie szukać w podkatalogu, można użyć os.listdir:

len([f for f in os.listdir(myPath) 
    if f.endswith('.tif') and os.path.isfile(os.path.join(myPath, f))]) 
Powiązane problemy