python資料夾檔案數量 - 如何列出目錄的所有文件?




python讀取資料夾 (20)

如何在Python中列出目錄的所有文件並將其添加到list

https://code.i-harness.com


獲取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')

第一部分1

初步說明

  • 雖然問題文本中的文件目錄術語之間存在明顯區別,但有些人可能認為目錄實際上是特殊文件
  • 聲明:“ 目錄的所有文件 ”可以用兩種方式解釋:
    1. 所有直接 (或1級)後代
    2. 整個目錄樹中的所有後代(包括子目錄中的後代)
  • 當問到這個問題時,我認為Python 2LTS版本,但是代碼示例將由Python 3.5 )運行 (我將盡可能保持它們與Python 2兼容;同樣,任何代碼屬於我要發布的Python來自v3.5.4 - 除非另有說明)。 這與問題中的另一個關鍵字有關:“ 將它們添加到列表中 ”:

    • Python 2之前的版本中,序列(iterables)主要由列表(元組,集合......)表示
    • Python 2.2中 ,引入了生成器[Python]:生成器 )的概念 - 由[Python]提供:yield語句 )。 隨著時間的推移,生成器對應物開始出現用於返回/使用列表的函數
    • Python 3中 ,生成器是默認行為
    • 現在,我不知道返回列表是否仍然是強制性的(或者生成器也可以這樣做),但是將生成器傳遞給list構造函數,將創建一個列表(並且還使用它)。 下面的例子說明了[Python]的不同之處mapfunction,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 ,但我也複製了UxLnx )的文件夾樹):

    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
    


解決方案

程序化方法:

  1. [Python]:os。 listdirpath ='。'

    返回一個列表,其中包含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']
    


  1. [Python]:os。 scandirpath ='。'!!! 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(在某些情況下,更快)


  1. [Python]:os。 walktop,topdown = True,onerror = None,followlinks = False

    通過從上到下或從下到上遍歷樹來生成目錄樹中的文件名。 對於以目錄top (包括top本身)為根的樹中的每個目錄,它會產生一個3元組( dirpathdirnamesfilenames )。


    >>> 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.listdiros.scandir如果可用)
    • 它通過在子文件夾中重複出現來進行繁重的工作


  1. [Python]:glob。globpathname,*,recursive = False[Python]:glob。iglobpathname,*,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是首選
    • 允許基於名稱的高級過濾(由於通配符)


  1. [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風格
    • 提供許多功能


  1. [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
    


  1. [人]:執行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邊緣
    • LinuxDirent64ctypes的的表示struct dirent64dirent.h(等等都是DT_*從我的機器常量):Ubtu 16 644.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']]
    


  1. [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']
    

    備註


  1. 安裝一些(其他)第三方軟件包
    • 最有可能的,將依賴於上述中的一個(或多個)(可能有輕微的自定義)


註釋(關於上面的內容):

  • 代碼是可移植的(除了針對特定區域的地方 - 標記的)或交叉:
    • 平台(UxWin,)
    • Python版本(2,3)
  • 在上述變體中使用了多種路徑樣式(絕對,親屬),以說明所使用的“工具”在這個方向上是靈活的
  • os.listdiros.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(如果一個條目的函數失敗,它將被跳過),但代碼變得越複雜,執行所需的時間就越長
  • 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))

參考@adamk的答案,這是我的os檢測方法,以響應@Anti Earth的斜線不一致性評論

from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]
[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

我假設您只想要列表中的basenames

有關預先定義方法1的多種文件格式,請參閱此post


如果您正在尋找一個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

所以我用它製作了一個PyPI package,還有一個GitHub存儲庫。我希望有人發現它可能對此代碼有用。


我假設您的所有文件都是*.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給出的目錄中的條目名稱。







directory