Python'daki geçerli dizindeki tüm alt dizinlerin listesini döndürmenin bir yolu var mı?
Bunu dosyalarla yapabileceğinizi biliyorum, ancak bunun yerine dizin listesini almam gerekiyor.
Python'daki geçerli dizindeki tüm alt dizinlerin listesini döndürmenin bir yolu var mı?
Bunu dosyalarla yapabileceğinizi biliyorum, ancak bunun yerine dizin listesini almam gerekiyor.
Yanıtlar:
Anında alt dizinler mi yoksa ağaç altındaki her dizin mi demek istediniz?
Her iki durumda da, bunu os.walk
yapmak için kullanabilirsiniz :
os.walk(directory)
her alt dizin için bir demet verir. 3 parçasındaki ilk girdi bir dizin adıdır, yani
[x[0] for x in os.walk(directory)]
size tüm alt dizinleri yinelemeli olarak vermelidir.
Gruptaki ikinci girişin, birinci konumdaki girişin alt dizinlerinin listesi olduğunu unutmayın, bunun yerine bunu kullanabilirsiniz, ancak sizi çok fazla kurtaramaz.
Ancak, bunu size hemen alt dizinleri vermek için kullanabilirsiniz:
next(os.walk('.'))[1]
Veya diğer çözümler zaten yayınlanmıştır kullanarak bkz os.listdir
ve os.path.isdir
"nde olanlar dahil, nasıl Python hemen alt dizinleri tüm almak için ".
os.walk('.').next()[1]
veya os.walk('.').__next__()[1]
doğrudan kullanmayın . Bunun yerine, next()
hem Python 2'de (bkz. Doc) hem de Python 3'te (bkz. Doc) bulunan yerleşik işlevi kullanın . Örneğin: next(os.walk('.'))[1]
.
os.walk('.').next()[1]
Doğrudan kullanmak neden kötü ?
iteraror.__next__()
dahili bir yöntemdir ve iterator.next()
kullanım next()
PEP-3114'e göre yerleşik olana geçirilmelidir. 2007'de onaylanan PEP-3114'e bakınız .
os.walk
Ve os.listdir
+ os.path.isdir
çözümleri arasındaki performans farkları hakkında endişe duyan herkes için : 10.000 alt dizin içeren bir dizinde test ettim (aşağıdaki hiyerarşide milyonlarca dosya var) ve performans farkları göz ardı edilebilir. os.walk
: "10 döngü, döngü başına 3: 44,6 milisaniyenin en iyisi" ve os.listdir
+ os.path.isdir
: "döngü başına 3 döngü: 45,1 milisaniyenin en iyisi"
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
üzerinde o
tam yolunu almak için aksi takdirde isdir(0)
her zaman false döndürür
os.path.join
iki kez, önce katılmak ve daha sonra kullanarak listeyi filtreleyebilirsiniz os.path.isdir
: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
Sadece kullanabilirsin glob.glob
from glob import glob
glob("/path/to/directory/*/")
/
Sonra izleyen unutmayın *
.
/
isimlerin
/
klasör ayırıcı olmak gerekirse, bu yapın:glob(os.path.join(path_to_directory, "*", ""))
recursive=True
Yukarıdakilerden çok daha güzel, çünkü birkaç os.path.join () öğesine ihtiyacınız yoktur ve tam yolu doğrudan alırsınız (isterseniz), bunu Python 3.5 ve üzeri ile yapabilirsiniz.
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
Bu, alt dizinin tam yolunu verecektir. Yalnızca alt dizinin adını kullanmak f.name
yerinef.path
https://docs.python.org/3/library/os.html#os.scandir
Biraz OT: Eğer ihtiyaç ardışık tüm alt klasör ve / veya ardışık tüm dosyalar , daha hızlı olan bu işlev bir göz var os.walk
ve glob
ve iyi olanlar (alt) alt klasörler içindeki tüm dosyaları gibi tüm alt klasörlerin bir listesini döndürür: https://stackoverflow.com/a/59803793/2441026
Yalnızca tüm alt klasörleri yinelemeli olarak istiyorsanız :
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
Tüm alt klasörlerin tam yollarını içeren bir listesini döndürür. Bu yine daha hızlı os.walk
ve çok daha hızlı glob
.
Tüm fonksiyonların analizi
tl; dr:
- Bir klasör kullanımı için hemen tüm alt dizinleri almak istiyorsanız os.scandir
.
- Tüm alt dizinleri, hatta iç içe geçmiş olanları almak istiyorsanız , yukarıdaki işlevi os.walk
veya - biraz daha hızlı kullanın fast_scandir
.
- Asla os.walk
sadece üst düzey alt dizinler için kullanmayın , çünkü yüzlerce (!) Kat daha yavaş olabilir os.scandir
.
os.walk
temel klasör olacaktır. Yani sadece alt dizinleri almayacaksınız. fu.pop(0)
Kaldırmak için kullanabilirsiniz .Sonuçlar :
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
W7x64, Python 3.8.1 ile test edilmiştir.
# -*- 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()
Alt dizinlerdeki tüm alt dizinleri bulan özyinelemeli bir çözüme ihtiyacınız varsa, daha önce önerildiği gibi walk komutunu kullanın.
Yalnızca geçerli dizinin alt dizinlerine ihtiyacınız varsa os.listdir
,os.path.isdir
Filtre kullanmayı tercih ediyorum ( https://docs.python.org/2/library/functions.html#filter ), ama bu sadece bir zevk meselesi.
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Bunu python-os-walk kullanarak uyguladı. ( 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)
Python 2.7 içindeki alt dizinlerin (ve dosyaların) listesini os.listdir (yol) kullanarak alabilirsiniz
import os
os.listdir(path) # list of subdirectories and files
os.listdir
Dosyaların dahil olduğu dizinin içeriğini listelediğine dikkat edin .
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)
Piton 3.4 kişiye modülü kolu dosya sistemi yolları için bir nesne yönelimli yaklaşım sağlar standart kitaplığı, içine: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('**/'))
Pathlib, PyPi'deki pathlib2 modülü aracılığıyla Python 2.7'de de mevcuttur .
for f in filter(Path.is_dir, p.iterdir()):
Python 3.4 ve Windows UNC yollarını kullanarak bu soruna tökezlediğim için, bu ortamın bir varyantı:
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, Python 3.4'te yenidir ve farklı işletim sistemleri altındaki yollarla çalışmayı çok daha kolay hale getirir: https://docs.python.org/3.4/library/pathlib.html
Bu soru uzun zaman önce cevaplanmış olmasına rağmen. pathlib
Modülü Windows ve Unix OS üzerinde çalışmanın güçlü bir yolu olduğu için kullanmanızı tavsiye ederim .
Dolayısıyla, alt dizinler dahil belirli bir dizindeki tüm yolları almak için:
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
vb.
İpuçları için teşekkürler çocuklar. Ben dirs olarak dönen softlink (sonsuz özyineleme) ile ilgili bir sorunla karşılaştı. Sembolik bağlantıları? Sızdırmaz yumuşak bağlantı istemiyoruz! Yani...
Bu sadece dirsekleri oluşturdu, yumuşak bağlantıları değil:
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
[x[0] for x in inf]
Bakabilmek için python'da ne denir?
Kopyalama yapıştırma dostu ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
Çıktı kaynağı print(folders)
:
['folderA', 'folderB']
x
tarafından oluşturulan listeden bir öğedir, os.listdir(d)
çünkü listeden herhangi bir dosyayı filtrelemek listdir
için filter
komutunu kullandığı dosya ve klasörleri döndürür os.path.isdir
.
Ben böyle yaparım.
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
@Blair Conrad'ın örneğine dayanan birkaç basit fonksiyon:
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]
Eli Bendersky'nin çözümünü temel alarak aşağıdaki örneği kullanın:
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"
nerede <your_directory>
gitmek istediğiniz dizinin yolu.
Bu cevap zaten mevcut değildi.
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
Son zamanlarda benzer bir soru yaşadım ve python 3.6 (kullanıcı havlock eklendi gibi) için en iyi cevap kullanmak olduğunu öğrendim os.scandir
. Kullanan bir çözüm olmadığı için kendim ekleyeceğim. İlk olarak, doğrudan kök dizinin altındaki alt dizinleri listeleyen özyinelemeli olmayan bir çözüm.
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
Özyinelemeli sürüm şöyle görünecektir:
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
alt dizine giden mutlak yolu kullanan unutmayın . Yalnızca klasör adına ihtiyacınız varsa kullanabilirsiniz entry.name
. Nesne hakkında ek ayrıntılar için os.DirEntry dosyasına bakın entry
.
böyle bir şey os.path.isdir
üzerinde bir filtre işlevi kullanos.listdir()
filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
Bu, tüm alt dizinleri dosya ağacının hemen altında listeler.
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 sürümünde yeni
Belirli bir dosya yolu içindeki tüm alt dizinlerin listesini döndürme işlevi. Tüm dosya ağacında arama yapar.
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
os.walk () kullanarak tüm klasörlerin listesini alabiliriz
import os
path = os.getcwd()
pathObject = os.walk(path)
Bu pathObject bir nesnedir ve bir dizi
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]) ....]
Tüm alt dizinlerin listesini arr üzerinden yineleyerek ve orta diziyi yazdırarak alabiliriz
for i in arr:
for j in i[1]:
print(j)
Bu, tüm alt dizini basacaktır.
Tüm dosyaları almak için:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
Bu işlev, belirli bir üst directory
öğeyle birlikte tüm directories
özyinelemeleri ve içinde bulduğu prints
her şeyi yineler filenames
. Çok faydalı.
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 ;")