পাইথনের বর্তমান ডিরেক্টরিতে সমস্ত উপ-ডিরেক্টরিগুলির একটি তালিকা ফেরত দেওয়ার কোনও উপায় আছে কি?
আমি জানি আপনি ফাইলগুলির মাধ্যমে এটি করতে পারেন, তবে পরিবর্তে ডিরেক্টরিগুলির তালিকা পাওয়া দরকার।
পাইথনের বর্তমান ডিরেক্টরিতে সমস্ত উপ-ডিরেক্টরিগুলির একটি তালিকা ফেরত দেওয়ার কোনও উপায় আছে কি?
আমি জানি আপনি ফাইলগুলির মাধ্যমে এটি করতে পারেন, তবে পরিবর্তে ডিরেক্টরিগুলির তালিকা পাওয়া দরকার।
উত্তর:
আপনি কি তাত্ক্ষণিক উপ-ডিরেক্টরি বা গাছের নীচে প্রতিটি ডিরেক্টরি বোঝাতে চাইছেন?
যে কোনও উপায়ে, আপনি এটি করতে ব্যবহার os.walk
করতে পারেন:
os.walk(directory)
প্রতিটি উপ-ডিরেক্টরিতে একটি টিপল দেবে। 3-tuple এর মধ্যে প্রথম এন্ট্রি একটি ডিরেক্টরি নাম, তাই
[x[0] for x in os.walk(directory)]
পুনরাবৃত্তির সাথে আপনাকে সমস্ত উপ-ডিরেক্টরিতে দেওয়া উচিত।
নোট করুন যে টুপলে দ্বিতীয় এন্ট্রিটি প্রথম অবস্থানে প্রবেশের চাইল্ড ডিরেক্টরিগুলির তালিকা, যাতে আপনি এটি পরিবর্তে ব্যবহার করতে পারেন তবে এটি আপনাকে বেশি সাশ্রয় করার সম্ভাবনা নেই।
তবে আপনি কেবলমাত্র তাৎক্ষণিক শিশু ডিরেক্টরিগুলি দেওয়ার জন্য এটি ব্যবহার করতে পারেন:
next(os.walk('.'))[1]
অথবা অন্য সমাধান ইতিমধ্যে, পোস্ট ব্যবহার দেখতে os.listdir
এবং os.path.isdir
"এ যারা সহ, কিভাবে পাইথন তাত্ক্ষণিক সাবডিরেক্টরি সব পেতে "।
os.walk('.').next()[1]
বা os.walk('.').__next__()[1]
সরাসরি ব্যবহার করবেন না । পরিবর্তে, অন্তর্নির্মিত ফাংশনটি ব্যবহার করুন next()
যা পাইথন 2 (ডক দেখুন) এবং পাইথন 3 ( দস্তাবেজ দেখুন) উভয় উপলভ্য । উদাহরণস্বরূপ: next(os.walk('.'))[1]
।
os.walk('.').next()[1]
সরাসরি ব্যবহার করা খারাপ কেন ?
iteraror.__next__()
এটি একটি অভ্যন্তরীণ পদ্ধতি এবং পিইপি -3114 অনুসারে ব্যবহারটি iterator.next()
বিল্ট-ইন-এ স্থানান্তরিত হওয়া উচিত next()
। দেখুন PEP-3114 যা 2007 সালে অনুমোদিত হয়
os.walk
এবং os.listdir
+ os.path.isdir
সমাধানগুলির মধ্যে পারফরম্যান্সের পার্থক্য সম্পর্কে উদ্বিগ্ন যে কারও জন্য : আমি 10,000 টি সাব-ডাইরেক্টরি (নীচে স্তরক্রমের কয়েক মিলিয়ন ফাইল সহ) সহ একটি ডিরেক্টরিতে পরীক্ষা করেছি এবং পারফরম্যান্সের পার্থক্য নগণ্য igible os.walk
: "10 লুপগুলি, প্রতি লুপটিতে 3: 44.6 এমসির মধ্যে সেরা" এবং os.listdir
+ os.path.isdir
: "10 লুপ, 3 লুপ প্রতি 3: 45.1
import os
d = '.'
[os.path.join(d, o) for o in os.listdir(d)
if os.path.isdir(os.path.join(d,o))]
os.path.join
উপর o
সম্পূর্ণ পথ পেতে, অন্যথায় isdir(0)
সবসময় মিথ্যা ফিরে আসবে
os.path.join
দু'বার কল এড়াতে , আপনি প্রথমে যোগদান করতে পারেন এবং তারপরে তালিকাটি ফিল্টার করতে পারেন os.path.isdir
: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
আপনি শুধু ব্যবহার করতে পারে glob.glob
from glob import glob
glob("/path/to/directory/*/")
এর /
পরে চলার পথটি ভুলে যাবেন না *
।
/
নামে
/
ফোল্ডার বিভাজক হিসাবে ধরে নিতে না পারেন তবে এটি করুন:glob(os.path.join(path_to_directory, "*", ""))
recursive=True
উপরের চেয়ে অনেক সুন্দর, কারণ আপনার বেশ কয়েকটি os.path.join () দরকার নেই এবং আপনি সরাসরি পুরো পথ পাবেন (যদি আপনি চান), আপনি পাইথন 3.5 এবং উপরের অংশে এটি করতে পারেন ।
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
এটি উপ-ডিরেক্টরিকে পুরো পথ দেবে। আপনি যদি কেবল এর f.name
পরিবর্তে সাব-ডিরেক্টরি ব্যবহারের নাম চানf.path
https://docs.python.org/3/library/os.html#os.scandir
কিছুটা ওটি: আপনার যদি সমস্ত সাবফোল্ডার পুনরাবৃত্তভাবে প্রয়োজন হয় এবং / অথবা সমস্ত ফাইল পুনরাবৃত্তভাবে প্রয়োজন হয় তবে এই ফাংশনটি একবার দেখুন: এটি os.walk
& এর চেয়ে দ্রুত glob
এবং সমস্ত সাবফোল্ডারগুলির তালিকা এবং সেই সাথে (সাব) ফোল্ডারের ভিতরে থাকা সমস্ত ফাইলের তালিকা ফিরিয়ে দেবে: https://stackoverflow.com/a/59803793/2441026
যদি আপনি কেবল সমস্ত সাবফোল্ডার পুনরাবৃত্তভাবে চান :
def fast_scandir(dirname):
subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
সমস্ত সাবফোল্ডারদের তাদের পুরো পাথ সহ একটি তালিকা ফেরত দেয়। এটি আবার দ্রুত os.walk
এবং এর চেয়ে অনেক দ্রুত glob
।
সমস্ত ফাংশন বিশ্লেষণ
tl; dr:
- আপনি যদি কোনও ফোল্ডার ব্যবহারের জন্য সমস্ত তাত্ক্ষণিক সাব-ডাইরেক্টরিগুলি পেতে চান os.scandir
।
- আপনি যদি সমস্ত সাব-ডাইরেক্টরিগুলি, এমনকি নেস্টেডও পেতে চান os.walk
তবে fast_scandir
উপরের ফাংশনটি ব্যবহার করুন বা - কিছুটা দ্রুত ।
- কখনও কখনও os.walk
কেবলমাত্র শীর্ষ-স্তরের সাব-ডাইরেক্টরির জন্য ব্যবহার করবেন না কারণ এটি কয়েকশো (!) বারের চেয়ে ধীর হতে পারে os.scandir
।
os.walk
হবে বেস ফোল্ডার। সুতরাং আপনি কেবল উপ-ডিরেক্টরি পাবেন না। আপনি fu.pop(0)
এটি অপসারণ করতে ব্যবহার করতে পারেন।ফলাফল :
os.scandir took 1 ms. Found dirs: 439
os.walk took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob took 20 ms. Found dirs: 439
pathlib.iterdir took 18 ms. Found dirs: 439
os.listdir took 18 ms. Found dirs: 439
ডাব্লু 7x64, পাইথন 3.8.1 এর সাথে পরীক্ষিত।
# -*- coding: utf-8 -*-
# Python 3
import time
import os
from glob import glob
from pathlib import Path
directory = r"<insert_folder>"
RUNS = 1
def run_os_walk():
a = time.time_ns()
for i in range(RUNS):
fu = [x[0] for x in os.walk(directory)]
print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_glob():
a = time.time_ns()
for i in range(RUNS):
fu = glob(directory + "/*/")
print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_pathlib_iterdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [f for f in dirname.iterdir() if f.is_dir()]
print(f"pathlib.iterdir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_listdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
print(f"os.listdir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_scandir():
a = time.time_ns()
for i in range(RUNS):
fu = [f.path for f in os.scandir(directory) if f.is_dir()]
print(f"os.scandir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")
if __name__ == '__main__':
run_os_scandir()
run_os_walk()
run_glob()
run_pathlib_iterdir()
run_os_listdir()
আপনার যদি একটি পুনরাবৃত্ত সমাধানের প্রয়োজন হয় যা উপ-ডিরেক্টরিতে সমস্ত উপ-ডিরেক্টরিগুলি খুঁজে পেতে পারে তবে আগে প্রস্তাবিত হিসাবে ওয়াক ব্যবহার করুন।
আপনার যদি কেবলমাত্র বর্তমান ডিরেক্টরিটির শিশু ডিরেক্টরি প্রয়োজন হয় তবে তার os.listdir
সাথে একত্রিত হনos.path.isdir
আমি ফিল্টার ব্যবহার করতে পছন্দ করি ( https://docs.python.org/2/library/funitions.html#filter ), তবে এটি কেবল স্বাদের বিষয়।
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
পাইথন-ওস-ওয়াক ব্যবহার করে এটি প্রয়োগ করা হয়েছে। ( http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/ )
import os
print("root prints out directories only from what you specified")
print("dirs prints out sub-directories from root")
print("files prints out all files from root and directories")
print("*" * 20)
for root, dirs, files in os.walk("/var/log"):
print(root)
print(dirs)
print(files)
পাইথন ২.7-এ আপনি os.listdir (পাথ) ব্যবহার করে উপ-ডিরেক্টরিগুলির (এবং ফাইলগুলি) তালিকা পেতে পারেন
import os
os.listdir(path) # list of subdirectories and files
os.listdir
ফাইলগুলি সহ ডিরেক্টরি বিষয়বস্তু তালিকাভুক্ত করে সে সম্পর্কে সাবধান থাকুন ।
print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)
files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)
পাইথন ৩.৪ স্ট্যান্ডার্ড লাইব্রেরিতে মডিউলটি প্রবর্তন করেছেpathlib
, যা ফাইল সিস্টেমের পাথগুলি পরিচালনা করতে একটি অবজেক্ট ওরিয়েন্টেড পদ্ধতির সরবরাহ করে:
from pathlib import Path
p = Path('./')
# List comprehension
[f for f in p.iterdir() if f.is_dir()]
# The trailing slash to glob indicated directories
# This will also include the current directory '.'
list(p.glob('**/'))
পাইথাইব পাইপাই-তে প্যাথলিব 2 মডিউলের মাধ্যমে পাইথন ২.7 এ উপলব্ধ।
for f in filter(Path.is_dir, p.iterdir()):
যেহেতু পাইথন ৩.৪ এবং উইন্ডোজ ইউএনসি পাথ ব্যবহার করে আমি এই সমস্যায় পড়েছি, এই পরিবেশের জন্য এখানে একটি বৈকল্পিক এখানে রয়েছে:
from pathlib import WindowsPath
def SubDirPath (d):
return [f for f in d.iterdir() if f.is_dir()]
subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$'))
print(subdirs)
পাইথন ৩.৪-এ নতুন এবং এটি বিভিন্ন ওএসের অধীনে পাথের সাথে কাজ করা আরও সহজ করে তোলে: https://docs.python.org/3.4/library/pathlib.html
যদিও এই প্রশ্নের উত্তর অনেক আগেই দেওয়া হয়েছিল। আমি pathlib
মডিউলটি ব্যবহারের জন্য সুপারিশ করতে চাই কারণ এটি উইন্ডোজ এবং ইউনিক্স ওএসে কাজ করার একটি শক্তিশালী উপায়।
সুতরাং সাব-ডিরেক্টরি সহ একটি নির্দিষ্ট ডিরেক্টরিতে সমস্ত পাথ পেতে:
from pathlib import Path
paths = list(Path('myhomefolder', 'folder').glob('**/*.txt'))
# all sorts of operations
file = paths[0]
file.name
file.stem
file.parent
file.suffix
প্রভৃতি
তোমাদের পরামর্শের জন্য ধন্যবাদ. আমি সফটলিঙ্কগুলি (অসীম পুনরাবৃত্তি) ডায়ার হিসাবে ফিরিয়ে দেওয়া নিয়ে একটি ইস্যুতে ছড়িয়ে পড়েছি। Softlinks? আমরা কোনও দুর্গন্ধযুক্ত নরম লিঙ্ক চাই না! তাই ...
এটি সফটলিঙ্কগুলি নয়, কেবল ডায়ারগুলি উপস্থাপন করেছে:
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
[x[0] for x in inf]
পাইথনকে কী বলা হয় যাতে আমি এটি সন্ধান করতে পারি?
কাস্ট পেস্ট বন্ধুত্বপূর্ণ ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
থেকে আউটপুট print(folders)
:
['folderA', 'folderB']
x
হ'ল তৈরি হওয়া তালিকা থেকে তৈরি আইটেম os.listdir(d)
কারণ listdir
তিনি যে ফাইলটি এবং ফোল্ডারগুলি তালিকা থেকে কোনও ফাইল ফিল্টার করার জন্য filter
কমান্ডটি ব্যবহার করছেন তা os.path.isdir
ফিরিয়ে দেবে।
এইভাবেই আমি এটি করি।
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
@ ব্লেয়ার কনরাডের উদাহরণের উপর ভিত্তি করে এখানে কয়েকটি সহজ কাজ রয়েছে -
import os
def get_subdirs(dir):
"Get a list of immediate subdirectories"
return next(os.walk(dir))[1]
def get_subfiles(dir):
"Get a list of immediate subfiles"
return next(os.walk(dir))[2]
এলি বেন্ডারস্কির সমাধানের ভিত্তিতে নিম্নলিখিত উদাহরণটি ব্যবহার করুন:
import os
test_directory = <your_directory>
for child in os.listdir(test_directory):
test_path = os.path.join(test_directory, child)
if os.path.isdir(test_path):
print test_path
# Do stuff to the directory "test_path"
<your_directory>
ডিরেক্টরিটি আপনি যে পথটি অনুসরণ করতে চান তা কোথায় ।
এই উত্তরটি ইতিমধ্যে বিদ্যমান বলে মনে হচ্ছে না।
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
আমি সম্প্রতি একটি অনুরূপ প্রশ্ন করেছি এবং আমি জানতে পেরেছি যে পাইথন ৩.6 (ব্যবহারকারী হ্যাভলক যুক্ত হিসাবে) এর সর্বোত্তম উত্তরটি ব্যবহার করা os.scandir
। যেহেতু মনে হচ্ছে এটি ব্যবহারের কোনও সমাধান নেই, তাই আমি আমার নিজস্ব যুক্ত করব। প্রথমত, একটি পুনরাবৃত্তির সমাধান যা মূল ডিরেক্টরিটির অধীনে কেবলমাত্র সাব-ডিরেক্টরিকে তালিকাবদ্ধ করে।
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
পুনরাবৃত্ত সংস্করণটি দেখতে এটির মতো হবে:
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist += get_dirlist(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
entry.path
সাব-ডাইরেক্টরির নিখুঁত পথটি মনে রাখবেন in আপনার যদি কেবল ফোল্ডারের নাম প্রয়োজন হয় তবে আপনি তার entry.name
পরিবর্তে ব্যবহার করতে পারেন । পড়ুন os.DirEntry সম্পর্কে অতিরিক্ত বিবরণের জন্য entry
বস্তু।
এই জাতীয় কিছু os.path.isdir
উপর একটি ফিল্টার ফাংশন ব্যবহার করুনos.listdir()
filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
এটি ফাইল গাছের নীচে সমস্ত উপ-ডিরেক্টরি তালিকাভুক্ত করবে।
import pathlib
def list_dir(dir):
path = pathlib.Path(dir)
dir = []
try:
for item in path.iterdir():
if item.is_dir():
dir.append(item)
dir = dir + list_dir(item)
return dir
except FileNotFoundError:
print('Invalid directory')
pathlib
সংস্করণ 3.4 এ নতুন
প্রদত্ত ফাইল পাথের মধ্যে সমস্ত উপ-ডিরেক্টরিগুলির একটি তালিকা ফেরত দেওয়ার কাজ। পুরো ফাইল ট্রি মাধ্যমে অনুসন্ধান করবে।
import os
def get_sub_directory_paths(start_directory, sub_directories):
"""
This method iterates through all subdirectory paths of a given
directory to collect all directory paths.
:param start_directory: The starting directory path.
:param sub_directories: A List that all subdirectory paths will be
stored to.
:return: A List of all sub-directory paths.
"""
for item in os.listdir(start_directory):
full_path = os.path.join(start_directory, item)
if os.path.isdir(full_path):
sub_directories.append(full_path)
# Recursive call to search through all subdirectories.
get_sub_directory_paths(full_path, sub_directories)
return sub_directories
আমরা ওএসওয়াক () ব্যবহার করে সমস্ত ফোল্ডারের তালিকা পেতে পারি
import os
path = os.getcwd()
pathObject = os.walk(path)
এই PathObject একটি অবজেক্ট এবং আমরা একটি অ্যারে পেতে পারি get
arr = [x for x in pathObject]
arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]
আমরা মাধ্যমে iterating সকল সাব তালিকা পেতে পারেন -Arr ও মাধ্যমিক অ্যারের মুদ্রণ
for i in arr:
for j in i[1]:
print(j)
এটি সমস্ত উপ-ডিরেক্টরি মুদ্রণ করবে।
সমস্ত ফাইল পেতে:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
একটি প্রদত্ত পিতা বা মাতা সঙ্গে এই ফাংশন, directory
সব তার উপর iterates directories
যাও recursively এবং prints
সব filenames
যা তা ভিতরে founds। খুব দরকারী।
import os
def printDirectoryFiles(directory):
for filename in os.listdir(directory):
full_path=os.path.join(directory, filename)
if not os.path.isdir(full_path):
print( full_path + "\n")
def checkFolders(directory):
dir_list = next(os.walk(directory))[1]
#print(dir_list)
for dir in dir_list:
print(dir)
checkFolders(directory +"/"+ dir)
printDirectoryFiles(directory)
main_dir="C:/Users/S0082448/Desktop/carpeta1"
checkFolders(main_dir)
input("Press enter to exit ;")