Python實(shí)現(xiàn)遍歷包含大量文件的文件夾
在處理大模型的訓(xùn)練數(shù)據(jù)時(shí),經(jīng)常需要遍歷大型文件夾,其中,可能包括數(shù)千萬(wàn)或數(shù)億個(gè)文件,這時(shí),一般的Python遍歷函數(shù)就會(huì)非常慢,例如os.walk、glob、path.rglob等等,同時(shí),無(wú)法預(yù)估整體的遍歷時(shí)間。
本文,通過(guò)Python的os.scandir,基于廣度優(yōu)先搜索算法,實(shí)現(xiàn)可控、高效的遍歷文件,同時(shí),輸出遍歷日志,支持后綴篩選,去除隱藏文件,實(shí)現(xiàn)遍歷包含大量文件的文件夾的功能。
os.scandir 是一個(gè)目錄迭代函數(shù),返回 os.DirEntry 對(duì)象的迭代器,對(duì)應(yīng)于由 path 指定目錄中的條目,這些條目以任意順序生成,不包括特殊條目 ‘.’ 和 ‘…’。os.scandir 的運(yùn)行效率要高于 os.walk,在 PEP 471 中,Python 官方也推薦使用 os.scandir 遍歷目錄 。
源碼
def traverse_dir_files_for_large(root_dir, ext=""): """ 列出文件夾中的文件, 深度遍歷 :param root_dir: 根目錄 :param ext: 后綴名 :return: 文件路徑列表 """ paths_list = [] dir_list = list() dir_list.append(root_dir) while len(dir_list) != 0: dir_path = dir_list.pop(0) dir_name = os.path.basename(dir_path) for i in tqdm(os.scandir(dir_path), f"[Info] dir {dir_name}"): path = i.path if path.startswith('.'): # 去除隱藏文件 continue if os.path.isdir(path): dir_list.append(path) else: if ext: # 根據(jù)后綴名搜索 if path.endswith(ext): paths_list.append(path) else: paths_list.append(path) return paths_list
輸出日志:
[Info] 初始化路徑開始!
[Info] 數(shù)據(jù)集路徑: /alphafoldDB/pdb_from_uniprot
[Info] dir pdb_from_uniprot: 256it [00:10, 24.47it/s]
[Info] dir 00: 240753it [00:30, 7808.36it/s]
[Info] dir 01: 241432it [00:24, 9975.56it/s]
[Info] dir 02: 240466it [00:24, 9809.68it/s]
[Info] dir 03: 241236it [00:22, 10936.76it/s]
[Info] dir 04: 241278it [00:24, 10011.14it/s]
[Info] dir 05: 241348it [00:25, 9414.16it/s]
補(bǔ)充
除了上文的方式,小編還為大家整理了其他Python遍歷文件夾的方法,需要的可以參考一下
方法一:通過(guò)os.walk()遍歷,直接處理文件即可
def traverse_dir_files(root_dir, ext=None, is_sorted=True): """ 列出文件夾中的文件, 深度遍歷 :param root_dir: 根目錄 :param ext: 后綴名 :param is_sorted: 是否排序,耗時(shí)較長(zhǎng) :return: [文件路徑列表, 文件名稱列表] """ names_list = [] paths_list = [] for parent, _, fileNames in os.walk(root_dir): for name in fileNames: if name.startswith('.'): # 去除隱藏文件 continue if ext: # 根據(jù)后綴名搜索 if name.endswith(tuple(ext)): names_list.append(name) paths_list.append(os.path.join(parent, name)) else: names_list.append(name) paths_list.append(os.path.join(parent, name)) if not names_list: # 文件夾為空 return paths_list, names_list if is_sorted: paths_list, names_list = sort_two_list(paths_list, names_list) return paths_list, names_list
方法二:通過(guò)pathlib.Path().rglob()遍歷,需要過(guò)濾出文件,速度較快。注意glob()不支持遞歸遍歷
def traverse_dir_files(root_dir, ext=None, is_sorted=True): """ 列出文件夾中的文件, 深度遍歷 :param root_dir: 根目錄 :param ext: 后綴名 :param is_sorted: 是否排序,耗時(shí)較長(zhǎng) :return: [文件路徑列表, 文件名稱列表] """ names_list = [] paths_list = [] for path in list(pathlib.Path(root_dir).rglob("*")): path = str(path) name = path.split("/")[-1] if name.startswith('.') or "." not in name: # 去除隱藏文件 continue if ext: # 根據(jù)后綴名搜索 if name.endswith(ext): names_list.append(name) paths_list.append(path) else: names_list.append(name) paths_list.append(path) if not names_list: # 文件夾為空 return paths_list, names_list if is_sorted: paths_list, names_list = sort_two_list(paths_list, names_list) return paths_list, names_list
到此這篇關(guān)于Python實(shí)現(xiàn)遍歷包含大量文件的文件夾的文章就介紹到這了,更多相關(guān)Python遍歷文件夾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django中Cookie設(shè)置及跨域問(wèn)題處理詳解
本文主要介紹了Django中Cookie設(shè)置及跨域問(wèn)題處理,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Python BeautifulSoup中文亂碼問(wèn)題的2種解決方法
這篇文章主要介紹了Python BeautifulSoup中文亂碼問(wèn)題的2種解決方法,需要的朋友可以參考下2014-04-04vscode調(diào)試django項(xiàng)目的方法
這篇文章主要介紹了vscode調(diào)試django項(xiàng)目的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08python實(shí)現(xiàn)不同數(shù)據(jù)庫(kù)間數(shù)據(jù)同步功能
這篇文章主要介紹了python實(shí)現(xiàn)不同數(shù)據(jù)庫(kù)間數(shù)據(jù)同步功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Pycharm github配置實(shí)現(xiàn)過(guò)程圖解
這篇文章主要介紹了Pycharm github配置實(shí)現(xiàn)過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10