357

Python を使用してディレクトリ内のファイルのリストを取得しようとしていますが、すべてのファイルのリストは必要ありません。

私が本質的に望んでいるのは、次のようなことを行う機能ですが、Python を使用して ls を実行しないことです。

ls 145592*.jpg

このための組み込みメソッドがない場合、現在、for ループを作成して an の結果を反復処理しos.listdir()、一致するすべてのファイルを新しいリストに追加することを考えています。

ただし、そのディレクトリには多くのファイルがあるため、より効率的な方法 (または組み込みの方法) があることを願っています。

4

13 に答える 13

495
import glob

jpgFilenamesList = glob.glob('145592*.jpg')

globPythonのドキュメントを参照してください

于 2010-02-08T23:05:18.390 に答える
155

glob.glob()間違いなくそれを行う方法です(Ignacioによる)。ただし、より複雑なマッチングが必要な場合は、リスト内包表記を使用してre.match()、次のように行うことができます。

files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)]

より柔軟ですが、ご存知のように、効率は低くなります。

于 2010-02-09T00:27:32.693 に答える
74

複雑にしないでおく:

import os
relevant_path = "[path to folder]"
included_extensions = ['jpg','jpeg', 'bmp', 'png', 'gif']
file_names = [fn for fn in os.listdir(relevant_path)
              if any(fn.endswith(ext) for ext in included_extensions)]

私はこの形のリスト内包表記を好みます。なぜなら、英語で読みやすいからです。

私は 4 行目を次のように読みました: 私のパスの os.listdir 内の各 fn について、含まれている拡張子のいずれかと一致するものだけを与えてください。

初心者の python プログラマーがフィルター処理にリスト内包表記を使用することに実際に慣れるのは難しいかもしれません。また、非常に大きなデータ セットの場合、メモリ オーバーヘッドが発生する可能性があります。文書化可能なコード。

この設計の唯一の点は、リストの代わりに文字列を渡すという間違いを防ぐことができないということです。たとえば、誤って文字列をリストに変換し、文字列のすべての文字をチェックしてしまうと、大量の誤検知が発生する可能性があります。

しかし、理解するのが難しい解決策よりも、修正しやすい問題がある方がよいでしょう。

于 2014-01-13T16:27:48.303 に答える
52

別のオプション:

>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']

https://docs.python.org/3/library/fnmatch.html

于 2016-01-28T11:55:54.597 に答える
15

予備コード

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path = '.'

解決策 1 - 「グロブ」を使用する

# lookup in current dir
glob.glob(pattern)

In [2]: glob.glob(pattern)
Out[2]: ['wsgi.py', 'manage.py', 'tasks.py']

解決策 2 - 「os」+「fnmatch」を使用

バリアント 2.1 - 現在のディレクトリでルックアップ

# lookup in current dir
fnmatch.filter(os.listdir(path), pattern)

In [3]: fnmatch.filter(os.listdir(path), pattern)
Out[3]: ['wsgi.py', 'manage.py', 'tasks.py']

バリアント 2.2 - ルックアップ再帰

# lookup recursive
for dirpath, dirnames, filenames in os.walk(path):

    if not filenames:
        continue

    pythonic_files = fnmatch.filter(filenames, pattern)
    if pythonic_files:
        for file in pythonic_files:
            print('{}/{}'.format(dirpath, file))

結果

./wsgi.py
./manage.py
./tasks.py
./temp/temp.py
./apps/diaries/urls.py
./apps/diaries/signals.py
./apps/diaries/actions.py
./apps/diaries/querysets.py
./apps/library/tests/test_forms.py
./apps/library/migrations/0001_initial.py
./apps/polls/views.py
./apps/polls/formsets.py
./apps/polls/reports.py
./apps/polls/admin.py

解決策 3 - 「pathlib」を使用する

# lookup in current dir
path_ = pathlib.Path('.')
tuple(path_.glob(pattern))

# lookup recursive
tuple(path_.rglob(pattern))

ノート:

  1. Python 3.4 でテスト済み
  2. モジュール「pathlib」は、Python 3.4 でのみ追加されました。
  3. Python 3.5 では、 glob.glob https://docs.python.org/3.5/library/glob.html#glob.globを使用した再帰ルックアップの機能が追加されました。私のマシンには Python 3.4 がインストールされているため、テストしていません。
于 2016-11-12T19:32:00.853 に答える
10

os.walk を使用して、ファイルを再帰的に一覧表示します

import os
root = "/home"
pattern = "145992"
alist_filter = ['jpg','bmp','png','gif'] 
path=os.path.join(root,"mydir_to_scan")
for r,d,f in os.walk(path):
    for file in f:
        if file[-3:] in alist_filter and pattern in file:
            print os.path.join(root,file)
于 2010-02-09T01:46:50.337 に答える
5
import os

dir="/path/to/dir"
[x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]

これにより、フル パスを含む jpg ファイルのリストが表示されます。ファイル名だけを にx[0]+"/"+f置き換えることができます。任意の文字列条件にf置き換えることもできます。f.endswith(".jpg")

于 2016-11-19T13:47:42.460 に答える
4

より高レベルのアプローチも好きかもしれません (私は実装し、findtoolsとしてパッケージ化しました):

from findtools.find_files import (find_files, Match)


# Recursively find all *.txt files in **/home/**
txt_files_pattern = Match(filetype='f', name='*.txt')
found_files = find_files(path='/home', match=txt_files_pattern)

for found_file in found_files:
    print found_file

でインストールできます

pip install findtools
于 2014-05-29T22:13:17.387 に答える