加速os.walk搜索特定文件类型的代码
我有一个函数,它可以遍历一个文件夹及其子文件夹,寻找特定类型的文件,这个功能本身没问题,但速度有点慢。有没有人能给我一些更“Pythonic”的建议,帮助我加快这个过程呢?
def findbyfiletype (filetype, directory):
"""
findbyfiletype allows the user to search by two parameters, filetype and directory.
Example:
If the user wishes to locate all pdf files with a directory including subdirectories
then the function would be called as follows:
findbyfiletype(".pdf", "D:\\\\")
this will return a dictionary of strings where the filename is the key and the file path is the value
e.g.
{'file.pdf':'c:\\folder\\file.pdf'}
note that both parameters filetype and directory must be enclosed in string double or single quotes
and the directory parameter must use the backslash escape \\\\ as opposed to \ as python will throw a string literal error
"""
indexlist =[] #holds all files in the given directory including sub folders
FiletypeFilenameList =[] #holds list of all filenames of defined filetype in indexlist
FiletypePathList = [] #holds path names to indvidual files of defined filetype
for root, dirs, files in os.walk(directory):
for name in files:
indexlist.append(os.path.join(root,name))
if filetype in name[-5:]:
FiletypeFilenameList.append(name)
for files in indexlist:
if filetype in files[-5:]:
FiletypePathList.append(files)
FileDictionary=dict(zip(FiletypeFilenameList, FiletypePathList))
del indexlist, FiletypePathList, FiletypeFilenameList
return FileDictionary
好吧,这就是我最后得到的结果,结合了@Ulrich Eckhardt、@Anton和@Cox的建议。
import os
import scandir
def findbyfiletype (filetype, directory):
FileDictionary={}
for root, dirs, files in scandir.walk(directory):
for name in files:
if filetype in name and name.endswith(filetype):
FileDictionary.update({name:os.path.join(root,name)})
return FileDictionary
如你所见,我对代码进行了重构,去掉了一些不必要的列表,并一步到位地创建了字典。@Anton,你提到的scandir模块真的帮了我大忙,让我在某个情况下速度提高了大约97%,这几乎让我惊呆了。
我把@Anton列为接受的答案,因为它总结了我通过重构所取得的成果,但@Ulrich Eckhardt和@Cox也都得到了点赞,因为你们都提供了很大的帮助。
祝好
2 个回答
1
walk() 这个函数可能会比较慢,因为它试图处理很多事情。
我用了一种简单的变体:
def walk(self, path):
try:
l = (os.path.join(path, x) for x in os.listdir(path))
for x in l:
if os.path.isdir(x):self.walk(x)
elif x.endswith(("jpg", "png", "jpeg")):
self.lf.append(x)
except PermissionError:pass
这样运行起来很快,而且 Python 会对文件系统进行本地缓存,所以第二次调用的时候会更快。
补充说明:这个 walk 函数是一个类的成员,所以你会看到“self”这个词。
编辑:在 NTFS 文件系统中,不用管 islink。可以用 try/except 来更新。
不过这样做只是忽略了你没有权限访问的文件夹。如果你想列出这些文件夹,你需要以管理员身份运行脚本。