2009-08-24 9 views
21

Ich bin ziemlich neu in Python und ich versuche herauszufinden, die effizienteste Möglichkeit, die Anzahl der. TIF-Dateien in einem bestimmten Unterverzeichnis zu zählen.Graf Anzahl der Dateien mit bestimmter Erweiterung in Python

einige der Suche, fand ich ein Beispiel (habe ich nicht getestet), die alle Dateien in einem Verzeichnis zu zählen behauptet:

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

Das ist in Ordnung, aber ich brauche nur TIF-Dateien zählen . Mein Verzeichnis enthält andere Dateitypen, aber ich möchte nur TIFs zählen.

Derzeit bin ich mit dem folgenden Code:

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

Es funktioniert gut, aber der Looping scheint mir übertrieben/teuer. Jeder Weg, dies effizienter zu tun?

Danke.

+0

Der effizienteste Weg, die Dinge in Python zu tun, oft werden sie in C zu tun . :) – Imagist

+3

Was magst du daran nicht? Was bedeutet "exzessiv"? Was bedeutet "teuer"? –

Antwort

32

Irgendetwas muss über alle Dateien im Verzeichnis iterieren und jeden einzelnen Dateinamen betrachten - ob das Ihr Code oder eine Bibliotheksroutine ist. Also, egal welche spezifische Lösung, sie werden alle ungefähr die gleichen Kosten haben.

Wenn Sie denken, es ist zu viel Code, und wenn Sie tatsächlich nicht rekursiv Unterverzeichnisse suchen müssen, können Sie das glob Modul verwenden:

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

Danke. Dies funktionierte gleich gut, und in 1/5 der Anzahl der Zeilen! Auch wenn es gleich teuer ist, sieht es schöner aus! :) –

+0

'glob1'? Warum undokumentierte Funktion verwenden? Warum nicht 'glob.glob' verwenden, das genau dasselbe Ergebnis liefert? – SilentGhost

+1

@SilentGhost: glob.glob erwartet nur einen einzelnen Parameter, der ein Pfadname ist. Im konkreten Fall ist das Verzeichnis bereits verfügbar, also muss es nicht erst hinzugefügt werden, nur damit glob es wieder teilen kann. Wenn myPath darüber hinaus ein glob-Zeichen enthält, würde glob.glob es interpretieren. –

4

Ihr Code ist in Ordnung.

Ja, Sie müssen diese Dateien durchlaufen, um die TIF-Dateien herauszufiltern, aber das Schleifen über ein kleines In-Memory-Array ist vernachlässigbar verglichen mit dem Durchsuchen des Dateiverzeichnisses nach diesen Dateien der erste Ort, den du sowieso machen musst.

Ich würde mir keine Sorgen über die Optimierung dieses Codes machen.

2

Wenn Sie rekursiv suchen brauchen, oder für einige anderer Grund nicht will, das glob Modul verwenden, Sie

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

Dies ist die „Pythonic“ Art und Weise anzupassen, das Beispiel, das Sie für Ihre Zwecke verwenden Sie können. Aber es wird nicht wesentlich schneller oder effizienter als die Schleife, die Sie verwendet haben; es ist nur eine sehr kompakte Syntax für mehr oder weniger die gleiche Sache.

+4

Seit wann beschreibt der Begriff "Pythonic" die Routine der Umwandlung von perfekt lesbaren 3 Codezeilen in eine einzige Zeile von verschachtelten For-Schleifen, die mindestens 5-mal so lang dauert, um PEP8 zu verstehen und dabei zu verletzen? –

+0

Da haben Leute so etwas in Python gemacht (und das ist schon eine Weile her). Aber beachte, dass ich "Pythonic" in Anführungszeichen gesetzt habe ("quote-Pythonic-unquote"), denn was in Python tatsächlich gemacht wird und was in PEP 8 spezifiziert ist, sind zwei verschiedene Dinge. –

4

Für diesen speziellen Anwendungsfall, wenn Sie rekursiv nicht im Unterverzeichnis suchen mögen, können Sie os.listdir verwenden:

len([f for f in os.listdir(myPath) 
    if f.endswith('.tif') and os.path.isfile(os.path.join(myPath, f))]) 
Verwandte Themen