Có cách nào để trả về một danh sách tất cả các thư mục con trong thư mục hiện tại trong Python không?
Tôi biết bạn có thể làm điều này với các tập tin, nhưng tôi cần phải có được danh sách các thư mục thay thế.
Có cách nào để trả về một danh sách tất cả các thư mục con trong thư mục hiện tại trong Python không?
Tôi biết bạn có thể làm điều này với các tập tin, nhưng tôi cần phải có được danh sách các thư mục thay thế.
Câu trả lời:
Bạn có nghĩa là thư mục con ngay lập tức, hoặc mọi thư mục ngay trên cây?
Dù bằng cách nào, bạn có thể sử dụng os.walk
để làm điều này:
os.walk(directory)
sẽ mang lại một tuple cho mỗi thư mục con. Mục đầu tiên trong 3-tuple là tên thư mục, vì vậy
[x[0] for x in os.walk(directory)]
sẽ cung cấp cho bạn tất cả các thư mục con, đệ quy.
Lưu ý rằng mục nhập thứ hai trong bộ dữ liệu là danh sách các thư mục con của mục nhập ở vị trí đầu tiên, vì vậy bạn có thể sử dụng mục này thay thế, nhưng nó không có khả năng giúp bạn tiết kiệm nhiều.
Tuy nhiên, bạn có thể sử dụng nó chỉ để cung cấp cho bạn các thư mục con ngay lập tức:
next(os.walk('.'))[1]
Hoặc xem các giải pháp khác đã được đăng, sử dụng os.listdir
và os.path.isdir
, bao gồm cả các giải pháp tại " Cách nhận tất cả các thư mục con ngay lập tức trong Python ".
os.walk('.').next()[1]
hoặc os.walk('.').__next__()[1]
trực tiếp. Thay vào đó, hãy sử dụng hàm dựng sẵn next()
, có sẵn trong cả Python 2 (xem doc) và Python 3 (xem doc) . Ví dụ : next(os.walk('.'))[1]
.
os.walk('.').next()[1]
trực tiếp?
iteraror.__next__()
là một phương thức nội bộ và iterator.next()
việc sử dụng nên được chuyển sang tích hợp next()
theo PEP-3114. Xem PEP-3114 đã được phê duyệt vào năm 2007
os.walk
và os.listdir
+ os.path.isdir
giải pháp: Tôi chỉ thử nghiệm trên một thư mục có 10.000 thư mục con (với hàng triệu tệp trong cấu trúc phân cấp bên dưới) và sự khác biệt về hiệu suất là không đáng kể. os.walk
: "10 vòng, tốt nhất là 3: 44,6 msec mỗi vòng" và os.listdir
+ os.path.isdir
: "10 vòng, tốt nhất là 3: 45,1 msec mỗi vòng"
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
trên o
để có được đường dẫn đầy đủ, nếu không isdir(0)
sẽ luôn luôn trả về false
os.path.join
hai lần, trước tiên bạn có thể tham gia và sau đó lọc danh sách bằng cách sử dụng os.path.isdir
: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
Bạn chỉ có thể sử dụng glob.glob
from glob import glob
glob("/path/to/directory/*/")
Đừng quên dấu vết /
sau *
.
/
trong tên
/
là trình phân tách thư mục, hãy làm điều này:glob(os.path.join(path_to_directory, "*", ""))
recursive=True
Đẹp hơn nhiều so với ở trên, vì bạn không cần vài os.path.join () và bạn sẽ nhận được đường dẫn đầy đủ trực tiếp (nếu bạn muốn), bạn có thể thực hiện điều này trong Python 3.5 trở lên.
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
Điều này sẽ đưa ra đường dẫn đầy đủ đến thư mục con. Nếu bạn chỉ muốn tên của thư mục con sử dụng f.name
thay vìf.path
https://docs.python.org/3/l Library / os.html # os.scandir
Hơi OT: Trong trường hợp bạn cần tất cả các thư mục con đệ quy và / hoặc tất cả các tệp đệ quy , hãy xem chức năng này, nhanh hơn os.walk
& glob
và sẽ trả về một danh sách tất cả các thư mục con cũng như tất cả các tệp bên trong các thư mục con (phụ) đó: https://stackoverflow.com/a/59803793/2441026
Trong trường hợp bạn chỉ muốn tất cả các thư mục con đệ quy :
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
Trả về một danh sách tất cả các thư mục con với đường dẫn đầy đủ của chúng. Điều này một lần nữa là nhanh hơn os.walk
và nhanh hơn rất nhiều glob
.
Một phân tích của tất cả các chức năng
tl; dr:
- Nếu bạn muốn nhận tất cả các thư mục con ngay lập tức để sử dụng thư mục os.scandir
.
- Nếu bạn muốn nhận tất cả các thư mục con, thậm chí các thư mục lồng nhau , hãy sử dụng os.walk
hoặc - nhanh hơn một chút - fast_scandir
chức năng trên.
- Không bao giờ chỉ sử dụng os.walk
cho các thư mục con cấp cao nhất, vì nó có thể chậm hơn hàng trăm (!) Lần os.scandir
.
os.walk
sẽ là thư mục cơ sở. Vì vậy, bạn sẽ không chỉ nhận được thư mục con. Bạn có thể sử dụng fu.pop(0)
để loại bỏ nó.Kết quả :
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
Đã thử nghiệm với 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()
Nếu bạn cần một giải pháp đệ quy sẽ tìm thấy tất cả các thư mục con trong thư mục con, hãy sử dụng đi bộ như đề xuất trước đó.
Nếu bạn chỉ cần thư mục con của thư mục hiện tại, kết hợp os.listdir
vớios.path.isdir
Tôi thích sử dụng bộ lọc ( https://docs.python.org/2/l Library / fiances.html # filter ), nhưng đây chỉ là vấn đề của hương vị.
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Thực hiện điều này bằng 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)
Bạn có thể lấy danh sách các thư mục con (và tệp) trong Python 2.7 bằng os.listdir (đường dẫn)
import os
os.listdir(path) # list of subdirectories and files
os.listdir
danh sách nội dung của thư mục bao gồm các tập tin.
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 giới thiệu các pathlib
mô-đun vào thư viện chuẩn, cung cấp một cách tiếp cận hướng đối tượng để xử lý đường dẫn hệ thống tập tin:
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 cũng có sẵn trên Python 2.7 thông qua mô đun pathlib2 trên PyPi.
for f in filter(Path.is_dir, p.iterdir()):
Vì tôi đã vấp phải sự cố này khi sử dụng các đường dẫn Python 3.4 và Windows UNC, đây là một biến thể cho môi trường này:
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 là phiên bản mới trong Python 3.4 và giúp làm việc với các đường dẫn trong các hệ điều hành khác nhau dễ dàng hơn nhiều: https://docs.python.org/3.4/l Library / pathlib.html
Mặc dù câu hỏi này đã được trả lời từ lâu. Tôi muốn khuyên bạn nên sử dụng pathlib
mô-đun vì đây là một cách mạnh mẽ để hoạt động trên hệ điều hành Windows và Unix.
Vì vậy, để có được tất cả các đường dẫn trong một thư mục cụ thể bao gồm các thư mục con:
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
Vân vân.
Nhờ những lời khuyên guys. Tôi gặp phải một vấn đề với các liên kết mềm (đệ quy vô hạn) được trả về dưới dạng thư mục. Liên kết mềm? Chúng tôi không muốn không có liên kết mềm của stinkin! Vì thế...
Điều này chỉ hiển thị các thư mục, không phải liên kết mềm:
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
[x[0] for x in inf]
gọi là trăn để tôi có thể tra cứu nó?
Sao chép dán thân thiện trong ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
Đầu ra từ print(folders)
:
['folderA', 'folderB']
x
là mục từ danh sách được tạo bởi os.listdir(d)
vì listdir
sẽ trả về các tệp và thư mục mà anh ta đang sử dụng filter
lệnh với os.path.isdir
để lọc bất kỳ tệp nào khỏi danh sách.
Đây là cách tôi làm điều đó.
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
Dưới đây là một số chức năng đơn giản dựa trên ví dụ của @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]
Dựa trên giải pháp của Eli Bendersky, hãy sử dụng ví dụ sau:
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"
nơi <your_directory>
là đường dẫn đến thư mục mà bạn muốn đi qua.
Câu trả lời này dường như không tồn tại.
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
Gần đây tôi đã có một câu hỏi tương tự và tôi phát hiện ra rằng câu trả lời tốt nhất cho python 3.6 (như người dùng đã thêm havlock) là sử dụng os.scandir
. Vì dường như không có giải pháp nào sử dụng nó, tôi sẽ tự thêm vào. Đầu tiên, một giải pháp không đệ quy chỉ liệt kê các thư mục con trực tiếp trong thư mục gốc.
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
Phiên bản đệ quy sẽ như thế này:
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
hãy nhớ rằng entry.path
sử dụng đường dẫn tuyệt đối đến thư mục con. Trong trường hợp bạn chỉ cần tên thư mục, bạn có thể sử dụng entry.name
thay thế. Tham khảo os.DirEntry để biết thêm chi tiết về entry
đối tượng.
sử dụng chức năng lọc os.path.isdir
trên os.listdir()
một cái gì đó như thế nàyfilter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
Điều này sẽ liệt kê tất cả các thư mục con ngay xuống cây tập tin.
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
là phiên bản mới 3,4
Chức năng trả về Danh sách tất cả các thư mục con trong một đường dẫn tệp đã cho. Sẽ tìm kiếm thông qua toàn bộ cây tập tin.
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
chúng ta có thể lấy danh sách tất cả các thư mục bằng cách sử dụng os.walk ()
import os
path = os.getcwd()
pathObject = os.walk(path)
này pathObject là một đối tượng và chúng tôi có thể nhận được một mảng bằng
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]) ....]
Chúng tôi có thể nhận được danh sách tất cả các thư mục con bằng cách duyệt qua arr và in mảng giữa
for i in arr:
for j in i[1]:
print(j)
Điều này sẽ in tất cả các thư mục con.
Để có được tất cả các tập tin:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
Hàm này, với một cha mẹ đã cho directory
lặp đi lặp lại trên tất cả directories
đệ quy của nó và prints
tất cả những filenames
gì nó tìm thấy bên trong. Quá hữu ích.
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 ;")