2009-08-24 22 views
21

私はPythonにはかなり新しく、特定のサブディレクトリにある.TIFファイルの数を数えられる最も効率的な方法を見つけようとしています。Pythonで特定の拡張子を持つファイルの数を数えよう

いくつかの検索を行う、私は(私がテストしていない)、ディレクトリ内のすべてのファイルをカウントするように主張した一例を見つけました:

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

これは結構ですが、私は唯一のTIFファイルをカウントする必要があります。私のディレクトリには他のファイルタイプが含まれていますが、私はTIFを数えたいだけです。

は現在、私は次のコードを使用しています:それは正常に動作しますが、

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

ループは私に/過度に高価であると思われます。これをより効率的に行う方法はありますか?

ありがとうございました。

+0

Pythonで物事を行うための最も効率的な方法は、Cでそれらを行うことが多いです。:) – Imagist

+3

あなたはこれについて気に入らないのですか? 「過剰」とはどういう意味ですか? 「高価」とはどういう意味ですか? –

答えて

32

何かがディレクトリ内のすべてのファイルを繰り返し処理しなければならず、コードまたはライブラリルーチンであるかどうかにかかわらず、すべてのファイル名を調べなければなりません。したがって、特定のソリューションが何であれ、それらはすべてほぼ同じコストを持ちます。

あなたはそれがあまりにも多くのコードだと思う場合は、あなたが実際に再帰的にサブディレクトリを検索する必要がない場合は、あなたがglobモジュールを使用することができます:あなたが再帰的に検索する必要がある場合

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

ありがとうございます。これは同じようにうまくいっていて、ラインの数の1/5に!たとえそれが同じであっても、それはもっときれいに見えます! :) –

+0

'glob1'?なぜドキュメント化されていない関数を使うのですか?まったく同じ結果を与える 'glob.glob'を使わないのはなぜですか? – SilentGhost

+1

@SilentGhost:glob.globは、単一のパラメータ(パス名)のみを必要とします。特定のケースでは、ディレクトリはすでに利用可能なので、最初に参加する必要はありません.Globで再度分割することができます。さらに、myPathにglob文字が含まれている場合、glob.globはそれを解釈します。 –

4

コードは問題ありません。

はい、これらのファイルをループして.tifファイルをフィルタリングする必要がありますが、メモリ内の小さな配列をループすることは、ファイルディレクトリをスキャンしてこれらのファイルを検索する作業に比べて無視できます。とにかくやらなければならない最初の場所です。

私はこのコードの最適化について心配しません。

2

を、またはいくつかのために他の理由は、これはあなたがあなたの目的で見つかった例を適応させる「Python的」な方法です

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

を使用することができ、globモジュールを使用する必要はありません。しかし、あなたが使っているループよりもはるかに速くて効率的ではありません。これは多かれ少なかれ同じ事のためのコンパクトな構文です。この特定のユースケースでは

+4

「pythonic」という用語は、完璧に読みやすい3行のコードを、入れ子になったforループの1行に変換するルーチンを記述していますが、その過程でPEP8を理解して違反するのに少なくとも5倍かかるでしょうか? –

+0

人々はPythonでこのようなことをしてきました(そして、それはずっとずっと続いています)。しかし、実際にはPythonで何が行われるのか、PEP 8で指定されるのは2つの異なることがあるので、私は "Python"を引用符で囲むことに注意してください( "引用 - Pythonic-unquote")。 –

4

、あなたは再帰的にサブディレクトリ内で検索したくない場合は、あなたがos.listdirを使用することができます。

len([f for f in os.listdir(myPath) 
    if f.endswith('.tif') and os.path.isfile(os.path.join(myPath, f))]) 
関連する問題