यह सबसे तेजी से समाधान मैं के साथ आ सकता है प्रतीत हो रहा है, और है की तुलना में तेजी os.walk
और एक बहुत किसी भी तुलना में तेजी से glob
समाधान ।
- यह आपको मूल रूप से बिना किसी लागत के सभी नेस्टेड सबफ़ोल्डर्स की एक सूची भी देगा।
- आप कई अलग-अलग एक्सटेंशन खोज सकते हैं।
- तुम भी बदलकर फ़ाइलों के लिए या तो पूर्ण पथ या सिर्फ नाम वापस जाने के लिए चुन सकते हैं
f.path
करने के लिए f.name
(सबफ़ोल्डर के लिए इसे बदल नहीं है!)।
Args: dir: str, ext: list
।
फ़ंक्शन दो सूची देता हैsubfolders, files
:।
विस्तृत गति के लिए नीचे देखें।
def run_fast_scandir(dir, ext): # dir: str, ext: list
subfolders, files = [], []
for f in os.scandir(dir):
if f.is_dir():
subfolders.append(f.path)
if f.is_file():
if os.path.splitext(f.name)[1].lower() in ext:
files.append(f.path)
for dir in list(subfolders):
sf, f = run_fast_scandir(dir, ext)
subfolders.extend(sf)
files.extend(f)
return subfolders, files
subfolders, files = run_fast_scandir(folder, [".jpg"])
गति विश्लेषण
विभिन्न तरीकों के लिए सभी सबफ़ोल्डर्स और मुख्य फ़ोल्डर के अंदर एक विशिष्ट फ़ाइल एक्सटेंशन के साथ सभी फाइलें प्राप्त करने के लिए।
tl; dr:
- fast_scandir
स्पष्ट रूप से जीतता है और os.walk को छोड़कर अन्य सभी समाधानों की तुलना में दोगुना है।
- os.walk
दूसरे स्थान पर है धीमे धीमे।
- उपयोग glob
करने से प्रक्रिया बहुत धीमी हो जाएगी।
- परिणामों में से कोई भी प्राकृतिक छँटाई का उपयोग नहीं करता है । इसका मतलब है कि परिणाम इस प्रकार होंगे: 1, 10, 2. प्राकृतिक छंटाई (1, 2, 10) प्राप्त करने के लिए, कृपया https://stackoverflow.com/a/48030307/2441026 पर एक नज़र डालें।
परिणाम:
fast_scandir took 499 ms. Found files: 16596. Found subfolders: 439
os.walk took 589 ms. Found files: 16596
find_files took 919 ms. Found files: 16596
glob.iglob took 998 ms. Found files: 16596
glob.glob took 1002 ms. Found files: 16596
pathlib.rglob took 1041 ms. Found files: 16596
os.walk-glob took 1043 ms. Found files: 16596
टेस्ट W7x64, पायथन 3.8.1, 20 रन के साथ किया गया। 439 (आंशिक रूप से नेस्टेड) सबफ़ोल्डर में 16596 फाइलें।
find_files
से है https://stackoverflow.com/a/45646357/2441026 और आप कई एक्सटेंशन के लिए खोज करने देता है।
fast_scandir
स्वयं द्वारा लिखा गया था और वह सबफ़ोल्डर्स की सूची भी लौटाएगा। आप इसे खोज करने के लिए एक्सटेंशन की एक सूची दे सकते हैं (मैंने एक प्रविष्टि के साथ एक सूची का परीक्षण किया जिसमें कोई सरल if ... == ".jpg"
और कोई महत्वपूर्ण अंतर नहीं था)।
# -*- coding: utf-8 -*-
# Python 3
import time
import os
from glob import glob, iglob
from pathlib import Path
directory = r"<folder>"
RUNS = 20
def run_os_walk():
a = time.time_ns()
for i in range(RUNS):
fu = [os.path.join(dp, f) for dp, dn, filenames in os.walk(directory) for f in filenames if
os.path.splitext(f)[1].lower() == '.jpg']
print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(fu)}")
def run_os_walk_glob():
a = time.time_ns()
for i in range(RUNS):
fu = [y for x in os.walk(directory) for y in glob(os.path.join(x[0], '*.jpg'))]
print(f"os.walk-glob\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(fu)}")
def run_glob():
a = time.time_ns()
for i in range(RUNS):
fu = glob(os.path.join(directory, '**', '*.jpg'), recursive=True)
print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(fu)}")
def run_iglob():
a = time.time_ns()
for i in range(RUNS):
fu = list(iglob(os.path.join(directory, '**', '*.jpg'), recursive=True))
print(f"glob.iglob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(fu)}")
def run_pathlib_rglob():
a = time.time_ns()
for i in range(RUNS):
fu = list(Path(directory).rglob("*.jpg"))
print(f"pathlib.rglob\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(fu)}")
def find_files(files, dirs=[], extensions=[]):
# https://stackoverflow.com/a/45646357/2441026
new_dirs = []
for d in dirs:
try:
new_dirs += [ os.path.join(d, f) for f in os.listdir(d) ]
except OSError:
if os.path.splitext(d)[1].lower() in extensions:
files.append(d)
if new_dirs:
find_files(files, new_dirs, extensions )
else:
return
def run_fast_scandir(dir, ext): # dir: str, ext: list
# https://stackoverflow.com/a/59803793/2441026
subfolders, files = [], []
for f in os.scandir(dir):
if f.is_dir():
subfolders.append(f.path)
if f.is_file():
if os.path.splitext(f.name)[1].lower() in ext:
files.append(f.path)
for dir in list(subfolders):
sf, f = run_fast_scandir(dir, ext)
subfolders.extend(sf)
files.extend(f)
return subfolders, files
if __name__ == '__main__':
run_os_walk()
run_os_walk_glob()
run_glob()
run_iglob()
run_pathlib_rglob()
a = time.time_ns()
for i in range(RUNS):
files = []
find_files(files, dirs=[directory], extensions=[".jpg"])
print(f"find_files\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(files)}")
a = time.time_ns()
for i in range(RUNS):
subf, files = run_fast_scandir(directory, [".jpg"])
print(f"fast_scandir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found files: {len(files)}. Found subfolders: {len(subf)}")