python讀取資料夾 - python資料夾檔案數量
如何列出目錄的所有文件? (20)
獲取Python 2和3的文件列表
我也在這裡做了一個簡短的視頻: Python:如何獲取目錄中的文件列表
os.listdir()
或.....如何獲取當前目錄中的所有文件(和目錄)(Python 3)
在Python 3中將文件放在當前目錄中的最簡單方法是這樣。 這很簡單; 使用os
模塊和listdir()函數,你將擁有該目錄中的文件(以及目錄中的最終文件夾,但你不會在子目錄中有文件,因為你可以使用walk - 我會稍後談談)。
>>> import os
>>> arr = os.listdir()
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
使用glob
我發現glob更容易選擇相同類型的文件或共同的東西。 請看以下示例:
import glob
txtfiles = []
for file in glob.glob("*.txt"):
txtfiles.append(file)
使用列表理解
import glob
mylist = [f for f in glob.glob("*.txt")]
使用os.path.abspath獲取完整路徑名
如您所知,您在上面的代碼中沒有文件的完整路徑。 如果需要擁有絕對路徑,可以使用os.path
模塊的另一個函數_getfullpathname
,將從os.listdir()
獲得的文件作為參數。 還有其他方法可以獲得完整路徑,我們稍後會檢查(我更換了,如mexmex所建議的,_getfullpathname和abspath
)。
>>> import os
>>> files_path = [os.path.abspath(x) for x in os.listdir()]
>>> files_path
['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']
使用walk獲取所有子目錄中的文件類型的完整路徑名
我發現這對於在許多目錄中查找內容非常有用,它幫助我找到了一個我不記得名字的文件:
import os
# Getting the current work directory (cwd)
thisdir = os.getcwd()
# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
for file in f:
if ".docx" in file:
print(os.path.join(r, file))
os.listdir():獲取當前目錄中的文件(Python 2)
在Python 2中,如果您想要當前目錄中的文件列表,則必須將參數設置為“。”。 或os.listdir方法中的os.getcwd()。
>>> import os
>>> arr = os.listdir('.')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
要進入目錄樹
>>> # Method 1
>>> x = os.listdir('..')
# Method 2
>>> x= os.listdir('/')
獲取文件:os.listdir()在特定目錄中(Python 2和3)
>>> import os
>>> arr = os.listdir('F:\\python')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
使用os.listdir()獲取特定子目錄的文件
import os
x = os.listdir("./content")
os.walk('。') - 當前目錄
>>> import os
>>> arr = next(os.walk('.'))[2]
>>> arr
['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']
glob模塊 - 所有文件
import glob
print(glob.glob("*"))
out:['content', 'start.py']
next(os.walk('。'))和os.path.join('dir','file')
>>> import os
>>> arr = []
>>> for d,r,f in next(os.walk("F:\_python")):
>>> for file in f:
>>> arr.append(os.path.join(r,file))
...
>>> for f in arr:
>>> print(files)
>output
F:\\_python\\dict_class.py
F:\\_python\\programmi.txt
next(os.walk('F:\') - 獲取完整路徑 - 列表理解
>>> [os.path.join(r,file) for r,d,f in next(os.walk("F:\\_python")) for file in f]
['F:\\_python\\dict_class.py', 'F:\\_python\\programmi.txt']
os.walk - 獲取完整路徑 - 子目錄中的所有文件
x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]
>>>x
['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']
os.listdir() - 只獲取txt文件
>>> arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
>>> print(arr_txt)
['work.txt', '3ebooks.txt']
glob - 只獲取txt文件
>>> import glob
>>> x = glob.glob("*.txt")
>>> x
['ale.txt', 'alunni2015.txt', 'assenze.text.txt', 'text2.txt', 'untitled.txt']
使用glob來獲取文件的完整路徑
如果我需要文件的絕對路徑:
>>> from path import path
>>> from glob import glob
>>> x = [path(f).abspath() for f in glob("F:\*.txt")]
>>> for f in x:
... print(f)
...
F:\acquistionline.txt
F:\acquisti_2018.txt
F:\bootstrap_jquery_ecc.txt
其他使用glob
如果我想要目錄中的所有文件:
>>> x = glob.glob("*")
使用os.path.isfile來避免列表中的目錄
import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)
> output
['a simple game.py', 'data.txt', 'decorator.py']
使用pathlib(Python 3.4)
import pathlib
>>> flist = []
>>> for p in pathlib.Path('.').iterdir():
... if p.is_file():
... print(p)
... flist.append(p)
...
error.PNG
exemaker.bat
guiprova.mp3
setup.py
speak_gui2.py
thumb.PNG
如果你想使用列表理解
>>> flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]
*您也可以使用pathlib.Path()而不是pathlib.Path(“。”)
在pathlib.Path()中使用glob方法
import pathlib
py = pathlib.Path().glob("*.py")
for file in py:
print(file)
輸出:
stack_overflow_list.py
stack_overflow_list_tkinter.py
使用os.walk獲取所有和唯一的文件
import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
for f in t:
y.append(f)
>>> y
['append_to_list.py', 'data.txt', 'data1.txt', 'data2.txt', 'data_180617', 'os_walk.py', 'READ2.py', 'read_data.py', 'somma_defaltdic.py', 'substitute_words.py', 'sum_data.py', 'data.txt', 'data1.txt', 'data_180617']
只獲取帶有next的文件並進入目錄
>>> import os
>>> x = next(os.walk('F://python'))[2]
>>> x
['calculator.bat','calculator.py']
只獲取下一個目錄並進入目錄
>>> import os
>>> next(os.walk('F://python'))[1] # for the current dir use ('.')
['python3','others']
使用walk獲取所有子目錄名稱
>>> for r,d,f in os.walk("F:\_python"):
... for dirs in d:
... print(dirs)
...
.vscode
pyexcel
pyschool.py
subtitles
_metaprogramming
.ipynb_checkpoints
來自Python 3.5的os.scandir()
>>> import os
>>> x = [f.name for f in os.scandir() if f.is_file()]
>>> x
['calculator.bat','calculator.py']
# Another example with scandir (a little variation from docs.python.org)
# This one is more efficient than os.listdir.
# In this case, it shows the files only in the current directory
# where the script is executed.
>>> import os
>>> with os.scandir() as i:
... for entry in i:
... if entry.is_file():
... print(entry.name)
...
ebookmaker.py
error.PNG
exemaker.bat
guiprova.mp3
setup.py
speakgui4.py
speak_gui2.py
speak_gui3.py
thumb.PNG
>>>
防爆。 1:子目錄中有多少個文件?
在此示例中,我們查找包含在所有目錄及其子目錄中的文件數。
import os
def count(dir, counter=0):
"returns number of files in dir and subdirs"
for pack in os.walk(dir):
for f in pack[2]:
counter += 1
return dir + " : " + str(counter) + "files"
print(count("F:\\python"))
> output
>'F:\\\python' : 12057 files'
例2:如何將目錄中的所有文件複製到另一個目錄?
一個腳本,用於在計算機中查找所有類型的文件(默認值:pptx)並將其複製到新文件夾中。
import os
import shutil
from path import path
destination = "F:\\file_copied"
# os.makedirs(destination)
def copyfile(dir, filetype='pptx', counter=0):
"Searches for pptx (or other - pptx is the default) files and copies them"
for pack in os.walk(dir):
for f in pack[2]:
if f.endswith(filetype):
fullpath = pack[0] + "\\" + f
print(fullpath)
shutil.copy(fullpath, destination)
counter += 1
if counter > 0:
print("------------------------")
print("\t==> Found in: `" + dir + "` : " + str(counter) + " files\n")
for dir in os.listdir():
"searches for folders that starts with `_`"
if dir[0] == '_':
# copyfile(dir, filetype='pdf')
copyfile(dir, filetype='txt')
> Output
_compiti18\Compito Contabilità 1\conti.txt
_compiti18\Compito Contabilità 1\modula4.txt
_compiti18\Compito Contabilità 1\moduloa4.txt
------------------------
==> Found in: `_compiti18` : 3 files
防爆。 3:如何獲取txt文件中的所有文件
如果您要創建包含所有文件名的txt文件:
import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
for eachfile in os.listdir():
mylist += eachfile + "\n"
file.write(mylist)
示例:txt包含硬盤驅動器的所有文件
"""We are going to save a txt file with all the files in your directory.
We will use the function walk()
"""
import os
# see all the methods of os
# print(*dir(os), sep=", ")
listafile = []
percorso = []
with open("lista_file.txt", "w", encoding='utf-8') as testo:
for root, dirs, files in os.walk("D:\\"):
for file in files:
listafile.append(file)
percorso.append(root + "\\" + file)
testo.write(file + "\n")
listafile.sort()
print("N. of files", len(listafile))
with open("lista_file_ordinata.txt", "w", encoding="utf-8") as testo_ordinato:
for file in listafile:
testo_ordinato.write(file + "\n")
with open("percorso.txt", "w", encoding="utf-8") as file_percorso:
for file in percorso:
file_percorso.write(file + "\n")
os.system("lista_file.txt")
os.system("lista_file_ordinata.txt")
os.system("percorso.txt")
C:\\的所有文件都在一個文本文件中
這是以前代碼的較短版本。 如果需要從其他位置開始,請更改文件夾從哪裡開始查找文件。 此代碼在我的計算機上生成一個50 MB的文本文件,其中包含少於500.000行,文件包含完整路徑。
import os
with open("file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk("C:\\"):
for file in f:
filewrite.write(f"{r + file}\n")
搜索特定類型文件的功能
進口口
def searchfiles(extension='.ttf'):
"Create a txt file with all the file of a type"
with open("file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk("C:\\"):
for file in f:
if file.endswith(extension):
filewrite.write(f"{r + file}\n")
# looking for ttf file (fonts)
searchfiles('ttf')
如何在Python中列出目錄的所有文件並將其添加到list
?
第一部分1
初步說明
- 雖然問題文本中的文件和目錄術語之間存在明顯區別,但有些人可能認為目錄實際上是特殊文件
- 聲明:“ 目錄的所有文件 ”可以用兩種方式解釋:
- 所有直接 (或1級)後代
- 整個目錄樹中的所有後代(包括子目錄中的後代)
當問到這個問題時,我認為Python 2是LTS版本,但是代碼示例將由Python 3 ( .5 )運行 (我將盡可能保持它們與Python 2兼容;同樣,任何代碼屬於我要發布的Python來自v3.5.4 - 除非另有說明)。 這與問題中的另一個關鍵字有關:“ 將它們添加到列表中 ”:
- 在Python 2之前的版本中,序列(iterables)主要由列表(元組,集合......)表示
- 在Python 2.2中 ,引入了生成器 ( [Python]:生成器 )的概念 - 由[Python]提供:yield語句 )。 隨著時間的推移,生成器對應物開始出現用於返回/使用列表的函數
- 在Python 3中 ,生成器是默認行為
- 現在,我不知道返回列表是否仍然是強制性的(或者生成器也可以這樣做),但是將生成器傳遞給
list
構造函數,將創建一個列表(並且還使用它)。 下面的例子說明了[Python]的不同之處: map ( function,iterable,... )
Python 2.7.10 (default, Mar 8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> m = map(lambda x: x, [1, 2, 3]) # Just a dummy lambda function >>> m, type(m) ([1, 2, 3], <type 'list'>) >>> len(m) 3
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> m = map(lambda x: x, [1, 2, 3]) >>> m, type(m) (<map object at 0x000001B4257342B0>, <class 'map'>) >>> len(m) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'map' has no len() >>> lm0 = list(m) # Construct a list out of the generator >>> lm0, type(lm0) ([1, 2, 3], <class 'list'>) >>> >>> lm1 = list(m) # Construct a list out of the same generator >>> lm1, type(lm1) # Empty list this time - generator already consumed ([], <class 'list'>)
這些示例將基於一個名為root_dir的目錄,具有以下結構(此示例適用於Win ,但我也複製了Ux ( Lnx )的文件夾樹):
E:\Work\Dev\\q003207219>tree /f "root_dir" Folder PATH listing for volume Work Volume serial number is 00000029 3655:6FED E:\WORK\DEV\\Q003207219\ROOT_DIR │ file0 │ file1 │ ├───dir0 │ ├───dir00 │ │ │ file000 │ │ │ │ │ └───dir000 │ │ file0000 │ │ │ ├───dir01 │ │ file010 │ │ file011 │ │ │ └───dir02 │ └───dir020 │ └───dir0200 ├───dir1 │ file10 │ file11 │ file12 │ ├───dir2 │ │ file20 │ │ │ └───dir20 │ file200 │ └───dir3
解決方案
程序化方法:
[Python]:os。 listdir ( path ='。' )
返回一個列表,其中包含path給出的目錄中的條目名稱。 該列表按任意順序排列,不包括特殊條目
'.'
和'..'
>>> import os >>> root_dir = "root_dir" # Path relative to current dir (os.getcwd()) >>> >>> os.listdir(root_dir) # List all the items in root_dir ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))] # Filter the items and only keep files (strip out directories) ['file0', 'file1']
這是一個更詳細的例子( code_os_listdir.py ):
import os from pprint import pformat def _get_dir_content(path, include_folders, recursive): entries = os.listdir(path) for entry in entries: entry_with_path = os.path.join(path, entry) if os.path.isdir(entry_with_path): if include_folders: yield entry_with_path if recursive: for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive): yield sub_entry else: yield entry_with_path def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True): path_len = len(path) + len(os.path.sep) for item in _get_dir_content(path, include_folders, recursive): yield item if prepend_folder_name else item[path_len:] def _get_dir_content_old(path, include_folders, recursive): entries = os.listdir(path) ret = list() for entry in entries: entry_with_path = os.path.join(path, entry) if os.path.isdir(entry_with_path): if include_folders: ret.append(entry_with_path) if recursive: ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive)) else: ret.append(entry_with_path) return ret def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True): path_len = len(path) + len(os.path.sep) return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)] def main(): root_dir = "root_dir" ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True) lret0 = list(ret0) print(ret0, len(lret0), pformat(lret0)) ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False) print(len(ret1), pformat(ret1)) if __name__ == "__main__": main()
備註 :
- 有兩種實現:
- 一個使用生成器(當然在這個例子中它似乎沒用,因為我立即將結果轉換為列表)
- 經典的(函數名以_old結尾)
- 使用遞歸(進入子目錄)
- 對於每個實現,有兩個功能:
- 以下劃線 ( _ )開頭的一個:“私人”(不應該直接調用) - 完成所有工作
- public one(前一個包裝器):它只是從返回的條目中剝離初始路徑(如果需要)。 這是一個醜陋的實現,但這是我在這一點上可以帶來的唯一想法
- 在性能方面,生成器通常要快一點(考慮創建和迭代時間),但我沒有在遞歸函數中測試它們,而且我在函數內部迭代內部生成器 - 不知道性能如何這是友好的
- 使用參數來獲得不同的結果
輸出 :
(py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py" <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0', 'root_dir\\dir0\\dir00', 'root_dir\\dir0\\dir00\\dir000', 'root_dir\\dir0\\dir00\\dir000\\file0000', 'root_dir\\dir0\\dir00\\file000', 'root_dir\\dir0\\dir01', 'root_dir\\dir0\\dir01\\file010', 'root_dir\\dir0\\dir01\\file011', 'root_dir\\dir0\\dir02', 'root_dir\\dir0\\dir02\\dir020', 'root_dir\\dir0\\dir02\\dir020\\dir0200', 'root_dir\\dir1', 'root_dir\\dir1\\file10', 'root_dir\\dir1\\file11', 'root_dir\\dir1\\file12', 'root_dir\\dir2', 'root_dir\\dir2\\dir20', 'root_dir\\dir2\\dir20\\file200', 'root_dir\\dir2\\file20', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] 11 ['dir0\\dir00\\dir000\\file0000', 'dir0\\dir00\\file000', 'dir0\\dir01\\file010', 'dir0\\dir01\\file011', 'dir1\\file10', 'dir1\\file11', 'dir1\\file12', 'dir2\\dir20\\file200', 'dir2\\file20', 'file0', 'file1']
- 有兩種實現:
[Python]:os。 scandir ( path ='。' ) ( !!! Python 3.5 + !!!雖然我認為對於早期版本它是一個單獨的模塊(也移植到Python 2 ))
返回與path給出的目錄中的條目對應的os.DirEntry對象的迭代器。 條目以任意順序產生,特殊條目
'.'
和'..'
不包括在內。使用scandir()而不是listdir()可以顯著提高還需要文件類型或文件屬性信息的代碼的性能,因為os.DirEntry對像在操作系統掃描目錄時提供此信息。 所有os.DirEntry方法都可以執行系統調用,但is_dir()和is_file()通常只需要對符號鏈接進行系統調用; os.DirEntry.stat()總是需要在Unix上進行系統調用,但在Windows上只需要一個符號鏈接。
>>> import os >>> root_dir = os.path.join(".", "root_dir") # Explicitly prepending current directory >>> root_dir '.\\root_dir' >>> >>> scandir_iterator = os.scandir(root_dir) >>> scandir_iterator <nt.ScandirIterator object at 0x00000268CF4BC140> >>> [item.path for item in scandir_iterator] ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1'] >>> >>> [item.path for item in scandir_iterator] # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension) [] >>> >>> scandir_iterator = os.scandir(root_dir) # Reinitialize the generator >>> for item in scandir_iterator : ... if os.path.isfile(item.path): ... print(item.name) ... file0 file1
備註 :
- 它類似於
os.listdir
- 但它也更靈活(並提供更多功能),更多Python ic(在某些情況下,更快)
- 它類似於
[Python]:os。 walk ( top,topdown = True,onerror = None,followlinks = False )
通過從上到下或從下到上遍歷樹來生成目錄樹中的文件名。 對於以目錄top (包括top本身)為根的樹中的每個目錄,它會產生一個3元組(
dirpath
,dirnames
,filenames
)。>>> import os >>> root_dir = os.path.join(os.getcwd(), "root_dir") # Specify the full path >>> root_dir 'E:\\Work\\Dev\\\\q003207219\\root_dir' >>> >>> walk_generator = os.walk(root_dir) >>> root_dir_entry = next(walk_generator) # First entry corresponds to the root dir (that was passed as an argument) >>> root_dir_entry ('E:\\Work\\Dev\\\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1']) >>> >>> root_dir_entry[1] + root_dir_entry[2] # Display the dirs and the files (that are direct descendants) in a single list ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]] # Display all the entries in the previous list by their full path ['E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file1'] >>> >>> for entry in walk_generator: # Display the rest of the elements (corresponding to every subdir) ... print(entry) ... ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], []) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], []) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], []) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], []) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', ['dir20'], ['file20']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2\\dir20', [], ['file200']) ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', [], [])
備註 :
- 在幕後,它使用
os.listdir
(os.scandir
如果可用) - 它通過在子文件夾中重複出現來進行繁重的工作
- 在幕後,它使用
[Python]:glob。glob(pathname,*,recursive = False)([Python]:glob。iglob(pathname,*,recursive = False))
返回匹配的路徑名可能空單路徑,它必須包含路徑規範的字符串。pathname可以是絕對(like
/usr/src/Python-1.5/Makefile
)或相對(like../../Tools/*/*.gif
),也可以包含shell樣式的通配符。結果中包含損壞的符號鏈接(如在shell中)。
...
在版本3.5中更改:使用“**
”支持遞歸globs。>>> import glob, os >>> wildcard_pattern = "*" >>> root_dir = os.path.join("root_dir", wildcard_pattern) # Match every file/dir name >>> root_dir 'root_dir\\*' >>> >>> glob_list = glob.glob(root_dir) >>> glob_list ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] >>> >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list] # Strip the dir name and the path separator from begining ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> for entry in glob.iglob(root_dir + "*", recursive=True): ... print(entry) ... root_dir\ root_dir\dir0 root_dir\dir0\dir00 root_dir\dir0\dir00\dir000 root_dir\dir0\dir00\dir000\file0000 root_dir\dir0\dir00\file000 root_dir\dir0\dir01 root_dir\dir0\dir01\file010 root_dir\dir0\dir01\file011 root_dir\dir0\dir02 root_dir\dir0\dir02\dir020 root_dir\dir0\dir02\dir020\dir0200 root_dir\dir1 root_dir\dir1\file10 root_dir\dir1\file11 root_dir\dir1\file12 root_dir\dir2 root_dir\dir2\dir20 root_dir\dir2\dir20\file200 root_dir\dir2\file20 root_dir\dir3 root_dir\file0 root_dir\file1
備註 :
- 用途
os.listdir
- 對於大樹(特別是如果
recursive
打開),iglob
是首選 - 允許基於名稱的高級過濾(由於通配符)
- 用途
[Python]:類pathlib。路徑(* pathsegments)(!!! Python 3 + !!!不知道是否向後移植)
>>> import pathlib >>> root_dir = "root_dir" >>> root_dir_instance = pathlib.Path(root_dir) >>> root_dir_instance WindowsPath('root_dir') >>> root_dir_instance.name 'root_dir' >>> root_dir_instance.is_dir() True >>> >>> [item.name for item in root_dir_instance.glob("*")] # Wildcard searching for all direct descendants ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()] # Display paths (including parent) for files only ['root_dir\\file0', 'root_dir\\file1']
備註 :
- 這是實現我們目標的一種方式
- 這是處理路徑的OOP風格
- 提供許多功能
[Python中]:dircache.listdir(路徑)(!!!中除去的Python 3 !)
- 但是,根據$ {} PYTHON_SRC_DIR /Lib/dircache.py:〜#20 +(從v2.7.14),它只是一個(薄)包裝過
os.listdir
def listdir(path): """List directory contents, using cache.""" try: cached_mtime, list = cache[path] del cache[path] except KeyError: cached_mtime, list = -1, [] mtime = os.stat(path).st_mtime if mtime != cached_mtime: list = os.listdir(path) list.sort() cache[path] = mtime, list return list
- 但是,根據$ {} PYTHON_SRC_DIR /Lib/dircache.py:〜#20 +(從v2.7.14),它只是一個(薄)包裝過
[人]:執行opendir(3) / [人]:READDIR(3) / [人]:CLOSEDIR(3)通過[Python中]:ctypes的-用於Python外國函數庫(!!! 的Ux特定!!!)
ctypes是Python的外部函數庫。它提供C兼容的數據類型,並允許在DLL或共享庫中調用函數。它可以用於在純Python中包裝這些庫。
code_ctypes.py:
#!/usr/bin/env python3 import sys from ctypes import Structure, \ c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \ CDLL, POINTER, \ create_string_buffer, get_errno, set_errno, cast, sizeof DT_DIR = 4 DT_REG = 8 char256 = c_char * 256 class LinuxDirent64(Structure): _fields_ = [ ("d_ino", c_ulonglong), ("d_off", c_longlong), ("d_reclen", c_ushort), ("d_type", c_ubyte), ("d_name", char256), ] LinuxDirent64Ptr = POINTER(LinuxDirent64) libc_dll = CDLL(None) opendir = libc_dll.opendir readdir = libc_dll.readdir closedir = libc_dll.closedir libc_dll.__errno_location.restype = POINTER(c_int) errno_loc_func = libc_dll.__errno_location def _get_errno(): return "errno: {:d}({:d})".format(get_errno(), errno_loc_func().contents.value) def get_dir_content(path): ret = [path, list(), list()] dir_stream = opendir(create_string_buffer(path.encode())) if (dir_stream == 0): print("opendir returned NULL ({:s})".format(_get_errno())) return ret set_errno(0) dirent_addr = readdir(dir_stream) while dirent_addr: dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr) dirent = dirent_ptr.contents name = dirent.d_name.decode() if dirent.d_type & DT_DIR: if name not in (".", ".."): ret[1].append(name) elif dirent.d_type & DT_REG: ret[2].append(name) dirent_addr = readdir(dir_stream) if get_errno() or errno_loc_func().contents.value: print("readdir returned NULL ({:s})".format(_get_errno())) closedir(dir_stream) return ret def main(): print("{:s} on {:s}\n".format(sys.version, sys.platform)) root_dir = "root_dir" entries = get_dir_content(root_dir) print(entries) if __name__ == "__main__": main()
備註 :
- 它從libc加載三個函數(在當前進程中加載)並調用它們(更多細節檢查[]:如何使用Python檢查文件是否存在?(@ CristiFati的答案) - 來自第4項的最後一個註釋。)這將使這種方法非常接近Python / C邊緣
-
LinuxDirent64
是ctypes的的表示struct dirent64
從dirent.h(等等都是DT_*
從我的機器常量):Ubtu 16 64(4.10.0-40泛型和libc6的-dev的:AMD64)。在其他版本/版本上,結構定義可能不同,如果是,則應更新ctypes別名,否則將產生未定義的行為 -
errno_loc_func
(以及與之相關的所有內容)是因為errno
在出現錯誤時設置了funcs ,我需要檢查它的值。顯然,get_errno
不起作用(名稱無效,opendir
返回NULL
,但get_errno
仍返回0),或者我還沒弄明白 - 它以
os.walk
格式返回數據。我沒有費心去遞歸,但從現有的代碼開始,這將是一個相當簡單的任務 - 在Win上一切都是可行的,數據(庫,函數,結構,常量,......)也不同
輸出:
[email protected]:~/work//q003207219$ ./code_ctypes.py 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux ['root_dir', ['dir3', 'dir2', 'dir0', 'dir1'], ['file0', 'file1']]
[ActiveState的]:win32file.FindFilesW(!!! 贏特定!!!)
使用Windows Unicode API檢索匹配的文件名列表。API FindFirstFileW / FindNextFileW / Find關閉函數的接口。
>>> import os, win32file, win32con >>> root_dir = "root_dir" >>> wildcard = "*" >>> root_dir_wildcard = os.path.join(root_dir, wildcard) >>> entry_list = win32file.FindFilesW(root_dir_wildcard) >>> len(entry_list) # Don't display the whole content as it's too long 8 >>> [entry[-2] for entry in entry_list] # Only display the entry names ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")] # Filter entries and only display dir names (except self and parent) ['dir0', 'dir1', 'dir2', 'dir3'] >>> >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)] # Only display file "full" names ['root_dir\\file0', 'root_dir\\file1']
備註 :
-
win32file.FindFilesW
是[GitHub]的一部分:Python for Windows(pywin32)擴展,它是WINAPI上的Python包裝器 - 文檔鏈接來自https://www.activestate.com,因為我沒有找到任何pywin32官方文檔
-
- 安裝一些(其他)第三方軟件包
- 最有可能的,將依賴於上述中的一個(或多個)(可能有輕微的自定義)
註釋(關於上面的內容):
- 代碼是可移植的(除了針對特定區域的地方 - 標記的)或交叉:
- 平台(Ux,Win,)
- Python版本(2,3)
- 在上述變體中使用了多種路徑樣式(絕對,親屬),以說明所使用的“工具”在這個方向上是靈活的
-
os.listdir
並os.scandir
使用opendir
/readdir
/closedir
([MSDN]:FindFirstFile函數 / [MSDN]:FindNextFile函數 / [MSDN]:FindClose函數)(通過“ $ {PYTHON_SRC_DIR} /Modules/posixmodule.c ”) -
win32file.FindFilesW
使用那些(特定於Win)函數(通過“ $ {PYWIN32_SRC_DIR} /win32/src/win32file.i ”) -
get_dir_content
(從#1點開始)可以使用這些方法中的任何一種來實現(有些需要更多的工作,更少的工作)- 可以完成一些高級過濾(而不僅僅是文件與 dir):例如,
include_folders
參數可以被另一個(例如filter_func
)替換,這將是一個以路徑作為參數的函數:(filter_func=lambda x: True
這不會刪除任何東西)在get_dir_content
類似的內容中if not filter_func(entry_with_path): continue
(如果一個條目的函數失敗,它將被跳過),但代碼變得越複雜,執行所需的時間就越長
- 可以完成一些高級過濾(而不僅僅是文件與 dir):例如,
- Nota bene!由於使用了遞歸,我必須提到我在我的筆記本電腦上進行了一些測試(Win 10 x64),與此問題完全無關,並且當遞歸級別達到(990 ... 1000)範圍內的某個值時(recursionlimit - 1000) (默認)),我得到 :)。如果目錄樹超過了該限制(我不是FS專家,所以我不知道這是否可能),這可能是一個問題。
我還必須提一下,我沒有嘗試增加recursionlimit,因為我沒有該領域的經驗(在不得不增加操作系統的堆棧之前我可以增加多少水平),但理論上如果dir深度大於最高可能的遞歸限制(在那台機器上),總會有失敗的可能性 - 代碼示例僅用於演示目的。這意味著我沒有考慮錯誤處理(我不認為有任何
try
/except
/else
/finally
塊),所以代碼不健壯(原因是:盡可能保持簡單和簡短)。對於生產,還應添加錯誤處理
第一部分結束1
1.由於Home的帖子(問題/答案)限制是30000個字符([SE.Meta]:了解你的限制:問題標題,帖子,圖像和鏈接的最大長度是多少?),答案分為兩部分。另請訪問[SO]:如何列出目錄的所有文件?(@CristiFati的答案 - “第二部分”)。
從目錄及其所有子目錄獲取完整文件路徑
import os
def get_filepaths(directory):
"""
This function will generate the file names in a directory
tree by walking the tree either top-down or bottom-up. For each
directory in the tree rooted at directory top (including top itself),
it yields a 3-tuple (dirpath, dirnames, filenames).
"""
file_paths = [] # List which will store all of the full filepaths.
# Walk the tree.
for root, directories, files in os.walk(directory):
for filename in files:
# Join the two strings in order to form the full filepath.
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths # Self-explanatory.
# Run the above function and store its results in a variable.
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")
- 我在上面的函數中提供的路徑包含3個文件 - 其中兩個位於根目錄中,另一個位於名為“SUBFOLDER”的子文件夾中。 您現在可以執行以下操作:
print full_file_paths
將打印列表:-
['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
-
如果您願意,可以打開並閱讀內容,或只關注擴展名為“.dat”的文件,如下面的代碼所示:
for f in full_file_paths:
if f.endswith(".dat"):
print f
/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat
返回絕對文件路徑列表,不會遞歸到子目錄
L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]
一個單行解決方案, 只獲取文件列表 (沒有子目錄):
filenames = next(os.walk(path))[2]
或絕對路徑名:
paths = [os.path.join(path,fn) for fn in next(os.walk(path))[2]]
以目錄作為參數執行findfiles(),它將返回其中所有文件的列表。
import sys
import os
from pathlib import Path
from glob import glob
platformtype = sys.platform
if platformtype == 'win32':
slash = "\\"
if platformtype == 'darwin':
slash = "/"
# TODO: How can I list all files of a directory in Python and add them to a list?
# Step 1 - List all files of a directory
# Method 1: Find only pre-defined filetypes (.txt) and no subfiles, answer provided by @adamk
dir1 = "%sfoo%sbar%s*.txt" % (slash)
_files = glob(dir1)
# Method 2: Find all files and no subfiles
dir2 = "%sfoo%sbar%s" % (slash)
_files = (x for x in Path("dir2").iterdir() if x.is_file())
# Method 3: Find all files and all subfiles
dir3 = "%sfoo%sbar" % (slash)
_files = (x for x in Path('dir3').glob('**/*') if x.is_file())
# Step 2 - Add them to a list
files_list = []
for eachfiles in _files:
files_basename = os.path.basename(eachfiles)
files_list.append(files_basename)
列出目錄中的所有文件:
import os
from os import path
files = [x for x in os.listdir(directory_path) if path.isfile(directory_path+os.sep+x)]
在這裡,您將獲得目錄中所有文件的列表。
如果要使用其他文件類型或獲取完整目錄,請使用此功能:
import os
os.listdir(path)
您應該使用os
模塊列出目錄內容。 os.listdir(".")
返回目錄的所有內容。 我們迭代結果並附加到列表中。
import os
content_list = []
for content in os.listdir("."): # "." means current directory
content_list.append(content)
print content_list
我更喜歡使用glob
模塊,因為它模式匹配和擴展。
import glob
print(glob.glob("/home/adam/*.txt"))
它將返回包含查詢文件的列表:
['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
Python 3.5引入了一種新的,更快的方法來遍歷目錄 - os.scandir()
。
例:
for file in os.scandir('/usr/bin'):
line = ''
if file.is_file():
line += 'f'
elif file.is_dir():
line += 'd'
elif file.is_symlink():
line += 'l'
line += '\t'
print("{}{}".format(line, file.name))
如果您正在尋找一個find的Python實現,這是我經常使用的配方:
from findtools.find_files import (find_files, Match)
# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)
for found_file in found_files:
print found_file
我假設您的所有文件都是*.txt
格式化的,並存儲在帶路徑的目錄中data/
。
可以使用glob模塊python
列出目錄的所有文件,並按fnames
以下方式將它們添加到名為的列表中:
import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
if len(list[i]) != check:
temp.append(list[i-1])
check = len(list[i])
else:
i = i + 1
count = count - 1
print temp
這是我的通用功能。它返回文件路徑而不是文件名列表,因為我發現它更有用。它有一些可選參數,使其具有多種功能。例如,我經常使用像pattern='*.txt'
或或類似的參數subfolders=True
。
(py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")"
dir0
dir1
dir2
dir3
file0
file1
通過使用os
庫。
import os
def findfiles(directory):
objects = os.listdir(directory) # find all objects in a dir
files = []
for i in objects: # check if very object in the folder ...
if os.path.isfile(os.path.join(directory, i)): # ... is a file.
files.append(i) # if yes, append it.
return files
def list_files(path):
# returns a list of names (with extension, without full path) of all files
# in folder path
files = []
for name in os.listdir(path):
if os.path.isfile(os.path.join(path, name)):
files.append(name)
return files
filenames = next(os.walk(path))[2]
這將返回所有文件和目錄的列表path
。
import os
for root, dirs,files in os.walk("your dir path", topdown=True):
for name in files:
print(os.path.join(root, name))
這將只返回文件列表,而不是子目錄。
import os
import os.path
def get_files(target_dir):
item_list = os.listdir(target_dir)
file_list = list()
for item in item_list:
item_dir = os.path.join(target_dir,item)
if os.path.isdir(item_dir):
file_list += get_files(item_dir)
else:
file_list.append(item_dir)
return file_list
在這裡,我使用遞歸結構。
import os
lst=os.listdir(path)
os.listdir返回一個列表,其中包含path給出的目錄中的條目名稱。