Apakah ada cara untuk mengembalikan daftar semua subdirektori dalam direktori saat ini dengan Python?
Saya tahu Anda bisa melakukan ini dengan file, tetapi saya harus mendapatkan daftar direktori sebagai gantinya.
Apakah ada cara untuk mengembalikan daftar semua subdirektori dalam direktori saat ini dengan Python?
Saya tahu Anda bisa melakukan ini dengan file, tetapi saya harus mendapatkan daftar direktori sebagai gantinya.
Jawaban:
Apakah maksud Anda subdirektori langsung, atau setiap direktori di bawah pohon?
Apa pun itu, Anda dapat menggunakannya os.walk
untuk melakukan ini:
os.walk(directory)
akan menghasilkan tuple untuk setiap subdirektori. Entri pertama dalam 3-tuple adalah nama direktori, jadi
[x[0] for x in os.walk(directory)]
seharusnya memberi Anda semua subdirektori, secara rekursif.
Perhatikan bahwa entri kedua dalam tuple adalah daftar direktori anak dari entri di posisi pertama, jadi Anda bisa menggunakan ini sebagai gantinya, tetapi sepertinya tidak akan banyak menghemat.
Namun, Anda bisa menggunakannya hanya untuk memberi Anda direktori anak langsung:
next(os.walk('.'))[1]
Atau lihat solusi lain yang sudah diposting, menggunakan os.listdir
dan os.path.isdir
, termasuk yang ada di " Cara mendapatkan semua subdirektori langsung dengan Python ".
os.walk('.').next()[1]
atau os.walk('.').__next__()[1]
langsung. Sebagai gantinya, gunakan fungsi bawaan next()
, yang tersedia baik dalam Python 2 (lihat doc) dan Python 3 (lihat doc) . Sebagai contoh: next(os.walk('.'))[1]
.
os.walk('.').next()[1]
secara langsung?
iteraror.__next__()
merupakan metode internal dan iterator.next()
penggunaan harus dialihkan ke bawaan next()
menurut PEP-3114. Lihat PEP-3114 yang disetujui pada 2007.
os.walk
dan os.listdir
+ os.path.isdir
solusi: Saya baru saja menguji pada direktori dengan 10.000 subdirektori (dengan jutaan file dalam hierarki di bawah) dan perbedaan kinerja dapat diabaikan. os.walk
: "10 loop, terbaik 3: 44,6 msec per loop" dan os.listdir
+ os.path.isdir
: "10 loop, terbaik dari 3: 45,1 msec per loop"
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
on o
untuk mendapatkan path lengkap, jika tidak isdir(0)
akan selalu kembali salah
os.path.join
dua kali, Anda dapat bergabung terlebih dahulu dan kemudian menyaring daftar menggunakan os.path.isdir
: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
Anda bisa menggunakannya glob.glob
from glob import glob
glob("/path/to/directory/*/")
Jangan lupa jejak /
setelah *
.
/
/
sebagai pemisah folder, lakukan ini:glob(os.path.join(path_to_directory, "*", ""))
recursive=True
Jauh lebih bagus daripada yang di atas, karena Anda tidak perlu beberapa os.path.join () dan Anda akan mendapatkan path lengkap secara langsung (jika Anda mau), Anda dapat melakukan ini dengan Python 3.5 dan lebih tinggi.
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
Ini akan memberikan path lengkap ke subdirektori. Jika Anda hanya ingin menggunakan nama subdirektori f.name
daripadaf.path
https://docs.python.org/3/library/os.html#os.scandir
Sedikit Sl: Jika Anda membutuhkan semua subfolder secara rekursif dan / atau semua file secara rekursif , lihat fungsi ini, yang lebih cepat dari os.walk
& glob
dan akan mengembalikan daftar semua subfolder serta semua file di dalam subfolder (sub-): https://stackoverflow.com/a/59803793/2441026
Jika Anda hanya menginginkan semua subfolder secara rekursif :
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
Mengembalikan daftar semua subfolder dengan jalur lengkapnya. Ini lagi lebih cepat daripada os.walk
dan jauh lebih cepat daripada glob
.
Analisis semua fungsi
tl; dr:
- Jika Anda ingin mendapatkan semua subdirektori langsung untuk penggunaan folder os.scandir
.
- Jika Anda ingin mendapatkan semua subdirektori, bahkan yang bersarang , gunakan os.walk
atau - sedikit lebih cepat - fast_scandir
fungsi di atas.
- Jangan pernah gunakan os.walk
hanya untuk subdirektori tingkat atas, karena bisa jadi ratusan (!) Kali lebih lambat daripada os.scandir
.
os.walk
akan menjadi folder dasar. Jadi, Anda tidak hanya akan mendapatkan subdirektori. Anda dapat menggunakannya fu.pop(0)
untuk menghapusnya.Hasil :
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
Diuji dengan W7x64, Python 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()
Jika Anda membutuhkan solusi rekursif yang akan menemukan semua subdirektori di subdirektori, gunakan walk seperti yang disarankan sebelumnya.
Jika Anda hanya perlu direktori anak direktori saat ini, gabungkan os.listdir
denganos.path.isdir
Saya lebih suka menggunakan filter ( https://docs.python.org/2/library/functions.html#filter ), tetapi ini hanya masalah selera.
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Diimplementasikan ini menggunakan python-os-walk. ( 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)
Anda bisa mendapatkan daftar subdirektori (dan file) di Python 2.7 menggunakan os.listdir (path)
import os
os.listdir(path) # list of subdirectories and files
os.listdir
daftar isi direktori termasuk file.
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)
Python 3.4 diperkenalkan pada pathlib
modul ke dalam perpustakaan standar, yang menyediakan pendekatan berorientasi objek untuk jalur menangani filesystem:
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('**/'))
Pathlib juga tersedia di Python 2.7 melalui modul pathlib2 di PyPi.
for f in filter(Path.is_dir, p.iterdir()):
Karena saya menemukan masalah ini menggunakan jalur Python 3.4 dan Windows UNC, inilah varian untuk lingkungan ini:
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)
Pathlib baru di Python 3.4 dan membuat bekerja dengan jalur di bawah berbagai OS jauh lebih mudah: https://docs.python.org/3.4/library/pathlib.html
Meskipun pertanyaan ini dijawab sejak lama. Saya ingin merekomendasikan untuk menggunakan pathlib
modul ini karena ini adalah cara yang kuat untuk bekerja pada Windows dan Unix OS.
Jadi untuk mendapatkan semua jalur dalam direktori tertentu termasuk subdirektori:
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
dll.
Terima kasih untuk tipsnya, kawan. Saya mengalami masalah dengan softlink (rekursi tak terbatas) yang dikembalikan sebagai dir. Softlink? Kami tidak ingin ada tautan lunak yang menyebalkan! Begitu...
Ini hanya menghasilkan dir, bukan softlink:
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
[x[0] for x in inf]
disebut dengan python sehingga saya bisa mencarinya?
Copy paste friendly di ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
Output dari print(folders)
:
['folderA', 'folderB']
x
adalah item dari daftar yang dibuat oleh os.listdir(d)
karena listdir
akan mengembalikan file dan folder yang dia gunakan dengan filter
perintah os.path.isdir
untuk menyaring file apa pun dari daftar.
Beginilah cara saya melakukannya.
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
Berikut adalah beberapa fungsi sederhana berdasarkan contoh @Blair Conrad -
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]
Membangun solusi Eli Bendersky, gunakan contoh berikut:
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"
di mana <your_directory>
jalur ke direktori yang ingin Anda lintasi.
Jawaban ini sepertinya belum ada.
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
Saya punya pertanyaan serupa baru-baru ini, dan saya menemukan bahwa jawaban terbaik untuk python 3.6 (seperti yang ditambahkan pengguna havlock) adalah menggunakan os.scandir
. Karena sepertinya tidak ada solusi menggunakannya, saya akan menambahkan sendiri. Pertama, solusi non-rekursif yang hanya mencantumkan subdirektori langsung di bawah direktori root.
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
Versi rekursif akan terlihat seperti ini:
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
perlu diingat bahwa entry.path
memegang jalur absolut ke subdirektori. Jika Anda hanya perlu nama folder, Anda dapat menggunakannya entry.name
. Lihat os.DirEntry untuk detail tambahan tentang entry
objek.
gunakan fungsi filter os.path.isdir
atas os.listdir()
sesuatu seperti inifilter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
Ini akan mencantumkan semua subdirektori di bawah pohon file.
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
baru dalam versi 3.4
Berfungsi untuk mengembalikan Daftar semua subdirektori dalam jalur file yang diberikan. Akan mencari melalui seluruh pohon file.
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
kita bisa mendapatkan daftar semua folder dengan menggunakan os.walk ()
import os
path = os.getcwd()
pathObject = os.walk(path)
pathObject ini adalah objek dan kita bisa mendapatkan array dengan
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]) ....]
Kita bisa mendapatkan daftar semua subdirektori dengan mengulangi melalui arr dan mencetak array tengah
for i in arr:
for j in i[1]:
print(j)
Ini akan mencetak semua subdirektori.
Untuk mendapatkan semua file:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
Fungsi ini, dengan orangtua yang diberikan directory
iterates atas semua secara directories
rekursif dan prints
semua filenames
yang ditemukan di dalamnya. Terlalu berguna
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 ;")