এই দ্রুততম সমাধান আমি সাথে আসতে পারেন বলে মনে হয়, এবং তুলনায় দ্রুততর 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
দ্বিতীয় স্থানে আস্তে ধীর।
- ব্যবহারের 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
টেস্টগুলি ডাব্লু 7x64, পাইথন 3.8.1, 20 রান দিয়ে হয়েছিল। 439 (আংশিক নেস্টেড) সাবফোল্ডারগুলিতে 16596 ফাইল। https://stackoverflow.com/a/45646357/2441026
find_files
থেকে এবং আপনাকে বেশ কয়েকটি এক্সটেনশান অনুসন্ধান করতে দেয়। আমি নিজে লিখেছিলাম এবং সাবফোল্ডারগুলির একটি তালিকাও ফিরিয়ে দেব। আপনি এটি অনুসন্ধানের জন্য এক্সটেনশনের একটি তালিকা দিতে পারেন (আমি একটি সরল প্রবেশের সাথে একটি তালিকা পরীক্ষা করেছি এবং কোনও তাত্পর্যপূর্ণ পার্থক্য ছিল না)।
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)}")