Как перечислить все файлы каталога?

Как я могу перечислить все файлы каталога в Python и добавить их в list?

Ответ 1

os.listdir() доставит вам все, что в каталоге - файлы и каталоги.

Если вам нужны только файлы, вы можете отфильтровать это, используя os.path:

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

или вы можете использовать os.walk() который выдаст два списка для каждого каталога, который он посещает, - разбив его на файлы и каталоги. Если вам нужен только верхний каталог, вы можете просто сломать его в первый раз

from os import walk

f = []
for (dirpath, dirnames, filenames) in walk(mypath):
    f.extend(filenames)
    break

Ответ 2

Я предпочитаю использовать модуль glob, так как он сопоставляет и расширяет шаблон.

import glob
print(glob.glob("/home/adam/*.txt"))

Он вернет список с запрошенными файлами:

['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]

Ответ 3

import os
os.listdir("somedirectory")

вернет список всех файлов и каталогов в "somedirectory".

Ответ 4

  Получить список файлов с Python 2 и 3


os.listdir()

Как получить все файлы (и каталоги) в текущем каталоге (Python 3)

Ниже приведены простые методы извлечения только файлов в текущем каталоге с использованием os и функции listdir() в Python 3. Дальнейшее изучение покажет, как вернуть папки в каталоге, но у вас не будет файла в подкаталог, для этого вы можете использовать walk - обсуждается позже).

 import os
 arr = os.listdir()
 print(arr)

 >>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

glob

Мне было легче выбрать файл того же типа или с чем-то общим. Посмотрите на следующий пример:

import glob

txtfiles = []
for file in glob.glob("*.txt"):
    txtfiles.append(file)

glob со списком

import glob

mylist = [f for f in glob.glob("*.txt")]

glob с функцией

import glob

def filebrowser():
    return [f for f in glob.glob("*")]

x = filebrowser()
print(x)

>>> ['example.txt', 'fb.py', 'filebrowser.py', 'help']

glob расширение предыдущего кода

Функция теперь возвращает список файлов, которые соответствуют строке, которую вы передаете в качестве аргумента

import glob

def filebrowser(word=""):
    """Returns a list with all files with the word/extension in it"""
    file = []
    for f in glob.glob("*"):
        if word in f:
            file.append(f)
            return file

flist = filebrowser("example")
print(flist)
flist = filebrowser(".py")
print(flist)

>>> ['example.txt']
>>> ['fb.py', 'filebrowser.py']

Получение полного пути с помощью os.path.abspath

Как вы заметили, у вас нет полного пути к файлу в приведенном выше коде. Если вам нужен абсолютный путь, вы можете использовать другую функцию модуля os.path под названием _getfullpathname, поместив в качестве аргумента файл, полученный из os.listdir(). Есть и другие способы получить полный путь, как мы проверим позже (я заменил, как это было предложено mexmex, _getfullpathname на abspath).

 import os
 files_path = [os.path.abspath(x) for x in os.listdir()]
 print(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.getcwd() в методе os.listdir.

 import os
 arr = os.listdir('.')
 print(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')
 print(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]
 print(arr)

 >>> ['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']

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)

>>> 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]
print(x)

>>> ['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']

os.listdir() - получать только текстовые файлы

 arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
 print(arr_txt)

 >>> ['work.txt', '3ebooks.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

Использование os.path.isfile, чтобы избежать каталогов в списке

import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)

>>> ['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

с list comprehension:

flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]

В качестве альтернативы, используйте pathlib.Path() вместо pathlib.Path(".")

Используйте метод glob в pathlib.Path()

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)
print(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]
 print(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

os.scandir() из Python 3.5 и выше

import os
x = [f.name for f in os.scandir() if f.is_file()]
print(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

Примеры:

Ex. 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"))

>>> '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('-' * 30)
        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')


>>> _compiti18\Compito Contabilità 1\conti.txt
>>> _compiti18\Compito Contabilità 1\modula4.txt
>>> _compiti18\Compito Contabilità 1\moduloa4.txt
>>> ------------------------
>>> ==> Found in: '_compiti18' : 3 files

Ex. 3: Как получить все файлы в текстовом файле

Если вы хотите создать текстовый файл со всеми именами файлов:

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 МБ текстового файла на моем компьютере с чем-то менее 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")

Как написать файл со всеми путями в папке типа

С помощью этой функции вы можете создать txt файл, который будет иметь имя типа искомого файла (например, pngfile.txt) со всем полным путем всех файлов этого типа. Я думаю, иногда это может быть полезно.

import os

def searchfiles(extension='.ttf', folder='H:\\'):
    "Create a txt file with all the file of a type"
    with open(extension[1:] + "file.txt", "w", encoding="utf-8") as filewrite:
        for r, d, f in os.walk(folder):
            for file in f:
                if file.endswith(extension):
                    filewrite.write(f"{r + file}\n")

# looking for png file (fonts) in the hard disk H:\
searchfiles('.png', 'H:\\')

>>> H:\4bs_18\Dolphins5.png
>>> H:\4bs_18\Dolphins6.png
>>> H:\4bs_18\Dolphins7.png
>>> H:\5_18\marketing html\assets\imageslogo2.png
>>> H:\7z001.png
>>> H:\7z002.png

(Новое) Найти все файлы и открыть их с помощью графического интерфейса tkinter

Я просто хотел добавить в это 2019 небольшое приложение для поиска всех файлов в каталоге и иметь возможность открывать их, дважды щелкнув по имени файла в списке. enter image description here

import tkinter as tk
import os

def searchfiles(extension='.txt', folder='H:\\'):
    "insert all files in the listbox"
    for r, d, f in os.walk(folder):
        for file in f:
            if file.endswith(extension):
                lb.insert(0, r + "\\" + file)

def open_file():
    os.startfile(lb.get(lb.curselection()[0]))

root = tk.Tk()
root.geometry("400x400")
bt = tk.Button(root, text="Search", command=lambda:searchfiles('.png', 'H:\\'))
bt.pack()
lb = tk.Listbox(root)
lb.pack(fill="both", expand=1)
lb.bind("<Double-Button>", lambda x: open_file())
root.mainloop()

Ответ 5

Решение в одну строку, чтобы получить только список файлов (без подкаталогов):

filenames = next(os.walk(path))[2]

или абсолютные пути:

paths = [os.path.join(path, fn) for fn in next(os.walk(path))[2]]

Ответ 6

Получение полных путей к файлу из каталога и всех его подкаталогов

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

Ответ 7

Начиная с версии 3.4 есть встроенные итераторы для этого, которые намного эффективнее, чем os.listdir():

pathlib: Новое в версии 3.4.

>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]

Согласно PEP 428, цель библиотеки pathlib состоит в том, чтобы обеспечить простую иерархию классов для обработки путей файловой системы и общих действий пользователей над ними.

os.scandir(): Новое в версии 3.5.

>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]

Обратите внимание, что os.walk() использует os.scandir() вместо os.listdir() из версии 3.5, и его скорость увеличивается в 2-20 раз в соответствии с PEP 471.

Позвольте мне также рекомендовать прочитать комментарий ShadowRanger ниже.

Ответ 8

Предварительные заметки

  • Хотя в тексте вопроса есть четкое различие между терминами файлов и каталогов, некоторые могут утверждать, что каталоги на самом деле являются специальными файлами.
  • Утверждение "все файлы каталога" можно интерпретировать двумя способами:
    1. Все прямые (или уровня 1) только потомки
    2. Все потомки во всем дереве каталогов (в том числе в подкаталогах)
  • Когда был задан вопрос, я представляю, что Python 2 был версией LTS, однако примеры кода будут выполняться Python 3 (.5) (я буду поддерживать их как Python 2-совместимые, насколько это возможно; также любой код, принадлежащий Python, который я собираюсь опубликовать, взят из версии 3.5.4 - если не указано иное). Это имеет последствия, связанные с другим ключевым словом в вопросе: "добавить их в список ":

    • В версиях, предшествующих Python 2.2, последовательности (итерируемые) в основном представляли собой списки (кортежи, множества,...)
    • В Python 2.2 была введена концепция генератора ([Python.Wiki]: Generators) - любезно предоставлена [Python 3]: оператор yield). Со временем начали появляться аналоги генератора для функций, которые возвращали/работали со списками
    • В Python 3 генератор является поведением по умолчанию
    • Не уверен, что возвращение списка все еще является обязательным (или генератор будет делать то же самое), но передача генератора конструктору списка создаст из него список (и также потребит его). Пример ниже иллюстрирует различия на [Python 3]: map (function, iterable,...)
    >>> import sys
    >>> sys.version
    '2.7.10 (default, Mar  8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)]'
    >>> m = map(lambda x: x, [1, 2, 3])  # Just a dummy lambda function
    >>> m, type(m)
    ([1, 2, 3], <type 'list'>)
    >>> len(m)
    3
    


    >>> import sys
    >>> sys.version
    '3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]'
    >>> 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)  # Build a list from the generator
    >>> lm0, type(lm0)
    ([1, 2, 3], <class 'list'>)
    >>>
    >>> lm1 = list(m)  # Build a list from the same generator
    >>> lm1, type(lm1)  # Empty list now - generator already consumed
    ([], <class 'list'>)
    
  • Примеры будут основаны на каталоге с именем root_dir со следующей структурой (этот пример для Win, но я также использую то же дерево на Lnx):

    E:\Work\Dev\StackOverflow\q003207219>tree /f "root_dir"
    Folder PATH listing for volume Work
    Volume serial number is 00000029 3655:6FED
    E:\WORK\DEV\STACKOVERFLOW\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 3]: ос. listdir (путь = '.')

    Вернуть список, содержащий имена записей в каталоге, заданном путем. Список приведен в произвольном порядке и не содержит специальных записей '.' и '..'...


    >>> 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 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)
    • Используется рекурсия (чтобы попасть в подкаталоги)
    • Для каждой реализации есть две функции:
      • Тот, который начинается с подчеркивания (_): "private" (не должен вызываться напрямую) - это делает всю работу
      • Открытый (обертка поверх предыдущего): он просто удаляет начальный путь (если требуется) из возвращенных записей. Это уродливая реализация, но это единственная идея, с которой я мог прийти в этот момент
    • С точки зрения производительности генераторы, как правило, немного быстрее (учитывая время создания и итерации), но я не проверял их в рекурсивных функциях, а также я перебираю функции внутри внутренних генераторов - не знаю, как производительность дружелюбный
    • Поиграйте с аргументами, чтобы получить разные результаты


    Выход:

    (py35x64_test) E:\Work\Dev\StackOverflow\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 3]: ос. ScanDir (путь = '') (Python 3.5 + портировать: [PyPI]: ScanDir)

    Возвратите итератор объектов 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
    • Но он также более гибкий (и предлагает больше функциональности), больше Pythonic (а в некоторых случаях быстрее)


  1. [Python 3]: ос. ходьба (top, topdown = True, onerror = None, последующие ссылки = False)

    Генерируйте имена файлов в дереве каталогов, обходя дерево сверху вниз или снизу вверх. Для каждого каталога в дереве с корнем в вершине каталога (включая саму вершину) он выдает 3-кортеж (dirpath, dirnames, filenames).


    >>> import os
    >>> root_dir = os.path.join(os.getcwd(), "root_dir")  # Specify the full path
    >>> root_dir
    'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir'
    >>>
    >>> walk_generator = os.walk(root_dir)
    >>> root_dir_entry = next(walk_generator)  # First entry corresponds to the root dir (passed as an argument)
    >>> root_dir_entry
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1'])
    >>>
    >>> root_dir_entry[1] + root_dir_entry[2]  # Display dirs and files (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\\StackOverflow\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file1']
    >>>
    >>> for entry in walk_generator:  # Display the rest of the elements (corresponding to every subdir)
    ...     print(entry)
    ...
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', ['dir20'], ['file20'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2\\dir20', [], ['file200'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', [], [])
    

    Примечания:

    • Под сценами он использует os.scandir (os.listdir в старых версиях)
    • Это делает тяжелую работу, возвращаясь в подпапках


  1. [Питон 3]: шар. glob (pathname, *, recursive = False) ([Python 3]: glob. iglob (pathname, *, recursive = False))

    Возврат возможно пустого списка имен путей, которые совпадают с путем, который должен быть строкой, содержащей спецификацию пути. имя_пути может быть абсолютным (например, /usr/src/Python-1.5/Makefile) или относительным (например, ../../Tools/*/*.gif) и может содержать подстановочные знаки в стиле оболочки. Сломанные символические ссылки включены в результаты (как в оболочке).
    ...
    Изменено в версии 3.5: Поддержка рекурсивных глобусов с использованием " ** ".


    >>> 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
    • Для больших деревьев (особенно если включена рекурсия), иглоб предпочтен
    • Позволяет расширенную фильтрацию по имени (из-за подстановочного знака)


  1. [Python 3]: class pathlib. Путь (* pathsegments) (Python 3.4 +, обратный порт: [PyPI]: pathlib2)

    >>> 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']
    

    Примечания:

    • Это один из способов достижения нашей цели
    • Это ООП стиль обработки путей
    • Предлагает множество функций


  1. [Python 2]: dircache.listdir (путь) (только Python 2)


    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. [man7]: OPENDIR (3)/[man7]: READDIR (3)/[man7]: CLOSEDIR (3) через [Python 3]: ctypes - библиотека сторонних функций для Python (специфична для POSIX)

    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
    
    
    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 = this_process = CDLL(None, use_errno=True)
    # ALWAYS set argtypes and restype for functions, otherwise it UB!!!
    opendir = libc_dll.opendir
    readdir = libc_dll.readdir
    closedir = libc_dll.closedir
    
    
    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 (errno: {:d})".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():
            print("readdir returned NULL (errno: {:d})".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 (загруженных в текущем процессе) и вызывает их (для более подробной информации проверьте [SO]: как проверить, существует ли файл без исключений? (Ответ @CristiFati) - последние заметки из пункта № 4.). Это поместило бы этот подход очень близко к краю Python/C
    • LinuxDirent64 - это представление ctypes для struct dirent64 из [man7]: dirent.h(0P) (как и константы DT_) с моей машины: Ubtu 16 x64 (4.10.0-40-generic и libc6-dev: amd64). В других вариантах/версиях определение структуры может отличаться, и если это так, псевдоним ctypes должен быть обновлен, в противном случае он приведет к неопределенному поведению
    • Возвращает данные в формате os.walk. Я не удосужился сделать его рекурсивным, но, исходя из существующего кода, это было бы довольно тривиальной задачей
    • На Win все также выполнимо, данные (библиотеки, функции, структуры, константы,...) отличаются


    Выход:

    [[email protected]:~/Work/Dev/StackOverflow/q003207219]> ./code_ctypes.py
    3.5.2 (default, Nov 12 2018, 13:43:14)
    [GCC 5.4.0 20160609] on linux
    
    ['root_dir', ['dir2', 'dir1', 'dir3', 'dir0'], ['file1', 'file0']]
    


  1. [ActiveState.Docs]: win32file.FindFilesW (зависит от выигрыша)

    Получает список совпадающих имен файлов с помощью Windows Unicode API. Интерфейс для API FindFirstFileW/FindNextFileW/Find close functions.


    >>> 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 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. Установите какой-нибудь (другой) сторонний пакет, который делает свое дело
    • Скорее всего, будет опираться на один (или несколько) из вышеперечисленных (возможно, с небольшими настройками)


Примечания:

  • Код должен быть переносимым (кроме мест, предназначенных для определенной области - которые отмечены) или крестиком:

    • платформа (Nix, Win,)
    • Версия Python (2, 3,)
  • Множество стилей пути (абсолютные, родственники) были использованы в вышеупомянутых вариантах, чтобы проиллюстрировать тот факт, что используемые "инструменты" являются гибкими в этом направлении

  • os.listdir и os.scandir используют opendir/readdir/closedir ([MS.Docs]: функция FindFirstFileW/[MS.Docs]: функция FindNextFileW/[MS.Docs]: функция FindClose) (через [GitHub]: python/cpython - (мастер) cpython/Modules/posixmodule.c)

  • win32file.FindFilesW использует эти (специфичные для Win) функции (через [GitHub]: mhammond/pywin32 - (master) pywin32/win32/src/win32file.i)

  • _get_dir_content (из пункта №1.) может быть реализован с использованием любого из этих подходов (некоторые потребуют больше работы, а некоторые меньше)

    • Может быть проделана некоторая расширенная фильтрация (вместо просто file vs. dir): например, аргумент include_folders можно заменить другим (например, filter_func), который будет функцией, которая принимает путь в качестве аргумента: filter_func=lambda x: True ( это ничего не убирает) и внутри _get_dir_content что-то вроде: if not filter_func(entry_with_path): continue (если функция завершается с ошибкой для одной записи, она будет пропущена), но чем сложнее код, тем дольше он займет выполнить
  • Нота бене! Поскольку используется рекурсия, я должен упомянуть, что я провел несколько тестов на своем ноутбуке (Win 10 x64), совершенно не связанных с этой проблемой, и когда уровень рекурсии достигал значений где-то в диапазоне (990.. 1000) (предел рекурсии - 1000 (по умолчанию)), я получил StackOverflow :). Если дерево каталогов превышает этот предел (я не эксперт FS, поэтому я не знаю, возможно ли это вообще), это может быть проблемой.
    Я должен также упомянуть, что я не пытался увеличить предел рекурсии, потому что у меня нет опыта в этой области (насколько я могу увеличить его, прежде чем придется увеличивать стек на уровне ОС), но в теории всегда будет возможность сбой, если глубина dir больше максимально возможного предела рекурсии (на этой машине)

  • Примеры кода приведены только для демонстрации. Это означает, что я не принимал во внимание обработку ошибок (я не думаю, что есть какой- либо блок try/кроме/else/finally), поэтому код не является устойчивым (причина в том, чтобы сделать его максимально простым и коротким, насколько это возможно).). Для производства должна быть добавлена обработка ошибок

Другие подходы:

  1. Используйте Python только в качестве оболочки

    • Все сделано с использованием другой технологии
    • Эта технология вызывается из Python
    • Самый известный вариант, который я знаю, это то, что я называю подходом системного администратора:

      • Используйте Python (или любой другой язык программирования в этом отношении) для выполнения команд оболочки (и анализа их выходных данных)
      • Некоторые считают это аккуратным хаком
      • Я считаю, что это больше похоже на неудачный обходной путь (gainarie), поскольку само по себе действие выполняется из оболочки (в данном случае cmd) и, следовательно, не имеет ничего общего с Python.
      • Фильтрация (grep/findstr) или форматирование вывода могут быть выполнены с обеих сторон, но я не буду настаивать на этом. Кроме того, я намеренно использовал os.system вместо subprocess.Popen.
      (py35x64_test) E:\Work\Dev\StackOverflow\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
      

    В общем случае такого подхода следует избегать, поскольку, если какой-либо формат вывода команды немного отличается между версиями/разновидностями ОС, код синтаксического анализа также должен быть адаптирован; не говоря уже о различиях между локалями).

Ответ 9

Мне действительно понравился ответ adamk, предлагая использовать glob() из модуля с тем же именем. Это позволяет вам сопоставлять шаблоны с * s.

Но, как отмечали другие люди в комментариях, glob() может столкнуться с несогласованными направлениями косой черты. Чтобы помочь в этом, я предлагаю вам использовать функции join() и expanduser() в модуле os.path и, возможно, функцию getcwd() в модуле os.

В качестве примеров:

from glob import glob

# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')

Это ужасно - путь жестко запрограммирован и будет работать только в Windows между именем диска и \, жестко закодированным в пути.

from glob    import glob
from os.path import join

# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))

Приведенное выше работает лучше, но оно зависит от имени папки Users, которое часто встречается в Windows и не так часто встречается на других ОС. Он также зависит от пользователя, имеющего определенное имя, admin.

from glob    import glob
from os.path import expanduser, join

# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))

Это отлично работает на всех платформах.

Еще один отличный пример, который отлично работает на разных платформах и делает что-то совсем другое:

from glob    import glob
from os      import getcwd
from os.path import join

# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))

Надеемся, что эти примеры помогут вам увидеть мощь нескольких функций, которые вы можете найти в стандартных библиотечных модулях Python.

Ответ 10

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 

Ответ 11

Вы должны использовать модуль os для размещения содержимого каталога. os.listdir(".") возвращает все содержимое каталога. Мы перебираем результат и добавляем его в список.

import os

content_list = []

for content in os.listdir("."): # "." means current directory
    content_list.append(content)

print content_list

Ответ 12

Если вы ищете реализацию 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, а также есть репозиторий GitHub. Я надеюсь, что кто-то найдет это потенциально полезным для этого кода.

Ответ 13

import os
lst=os.listdir(path)

os.listdir возвращает список, содержащий имена записей в каталоге, заданном путем.

Ответ 14

Python 3.5 представил новый, более быстрый метод для os.scandir() по каталогу - 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))

Ответ 15

Возврат списка абсолютных путей к файлу, не рекурсивно вложенные подкаталоги

L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]

Ответ 16

Список всех файлов в каталоге:

import os
from os import path

files = [x for x in os.listdir(directory_path) if path.isfile(directory_path+os.sep+x)]

Здесь вы получаете список всех файлов в каталоге.

Ответ 17

Для больших результатов вы можете использовать listdir() модуля os вместе с генератором (генератор - мощный итератор, который сохраняет свое состояние, помните?). Следующий код прекрасно работает с обеими версиями: Python 2 и Python 3.

Вот код:

import os

def files(path):  
    for file in os.listdir(path):
        if os.path.isfile(os.path.join(path, file)):
            yield file

for file in files("."):  
    print (file)

Метод listdir() возвращает список записей для данного каталога. Метод os.path.isfile() возвращает True если данная запись является файлом. И оператор yield выходит из функции, но сохраняет свое текущее состояние и возвращает только имя записи, обнаруженной как файл. Все вышеперечисленное позволяет нам зациклить функцию генератора.

Ответ 18

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

Здесь я использую рекурсивную структуру.

Ответ 19

Я предполагаю, что все ваши файлы имеют формат *.txt и хранятся в каталоге с data/ пути data/.

Можно использовать глобальный модуль python для fnames списка всех файлов каталога и добавления их в список с именем fnames следующим образом:

import glob

fnames = glob.glob("data/*.txt")  #fnames: list data type

Ответ 20

Однажды один мудрый учитель сказал мне:

Когда есть несколько установленных способов сделать что-то, ни один из них не подходит для всех случаев.

Таким образом, я добавлю решение для подмножества проблемы: довольно часто мы только хотим проверить, соответствует ли файл начальной и конечной строкам, не заходя в подкаталоги. Таким образом, нам нужна функция, которая возвращает список имен файлов, например:

filenames = dir_filter('foo/baz', radical='radical', extension='.txt')

Если вы хотите сначала объявить две функции, это можно сделать:

def file_filter(filename, radical='', extension=''):
    "Check if a filename matches a radical and extension"
    if not filename:
        return False
    filename = filename.strip()
    return(filename.startswith(radical) and filename.endswith(extension))

def dir_filter(dirname='', radical='', extension=''):
    "Filter filenames in directory according to radical and extension"
    if not dirname:
        dirname = '.'
    return [filename for filename in os.listdir(dirname)
                if file_filter(filename, radical, extension)]

Это решение может быть легко обобщено с помощью регулярных выражений (и вы можете добавить аргумент pattern, если вы не хотите, чтобы ваши шаблоны всегда придерживались начала или конца имени файла).

Ответ 21

Использование генераторов

import os
def get_files(search_path):
     for (dirpath, _, filenames) in os.walk(search_path):
         for filename in filenames:
             yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
    print(filename)

Ответ 22

import os 
os.listdir(path)

Это вернет список всех файлов и каталогов в path.

filenames = next(os.walk(path))[2]

Это вернет только список файлов, а не подкаталогов.

Ответ 23

# -** coding: utf-8 -*-
import os
import traceback

print '\n\n'

def start():
    address = "/home/ubuntu/Desktop"
    try:
        Folders = []
        Id = 1
        for item in os.listdir(address):
            endaddress = address + "/" + item
            Folders.append({'Id': Id, 'TopId': 0, 'Name': item, 'Address': endaddress })
            Id += 1         

            state = 0
            for item2 in os.listdir(endaddress):
                state = 1
            if state == 1: 
                Id = FolderToList(endaddress, Id, Id - 1, Folders)
        return Folders
    except:
        print "___________________________ ERROR ___________________________\n" + traceback.format_exc()

def FolderToList(address, Id, TopId, Folders):
    for item in os.listdir(address):
        endaddress = address + "/" + item
        Folders.append({'Id': Id, 'TopId': TopId, 'Name': item, 'Address': endaddress })
        Id += 1

        state = 0
        for item in os.listdir(endaddress):
            state = 1
        if state == 1: 
            Id = FolderToList(endaddress, Id, Id - 1, Folders)
    return Id

print start()

Ответ 24

Если вы заботитесь о производительности, попробуйте scandir. Для Python 2.x вам может потребоваться установить его вручную. Примеры:

# python 2.x
import scandir
import sys

de = scandir.scandir(sys.argv[1])
while 1:
    try:
        d = de.next()
        print d.path
    except StopIteration as _:
        break

Это экономит много времени, когда вам нужно сканировать огромный каталог, и вам не нужно буферизировать огромный список, просто выберите один за другим. А также вы можете сделать это рекурсивно:

def scan_path(path):
    de = scandir.scandir(path)
    while 1:
        try:
            e = de.next()
            if e.is_dir():
                scan_path(e.path)
            else:
                print e.path
        except StopIteration as _:
                break

Ответ 25

Вы можете использовать этот код для получения итератора, который запускается по всему пути к файлам (каталоги + имя файла).

import os

def get_iterator_all_files_name(dir_path):
    for (dirpath, dirnames, filenames) in os.walk(dir_path):
        for f in filenames:
            yield os.path.join(dirpath, f)

Или используйте это, чтобы получить это в списке.

import os

def get_list_all_files_name(dir_path):
    all_files_path = []

    for (dirpath, dirnames, filenames) in os.walk(dir_path):
        for f in filenames:
            all_files_path.append(os.path.join(dirpath, f))

    return all_files_path

Ответ 26

Другой очень читаемый вариант для Python 3. 4+ использует pathlib.Path.glob:

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

Просто сделать более конкретным, например, искать только исходные файлы Python, которые не являются символическими ссылками, также во всех подкаталогах:

[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

Ответ 27

dircache " устарел с версии 2.6: модуль dircache был удален в Python 3.0".

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

Ответ 28

Используя os библиотеку.

import os
for root, dirs,files in os.walk("your dir path", topdown=True):
    for name in files:
        print(os.path.join(root, name))

Ответ 29

Используйте эту функцию, если вы хотите использовать другой тип файла или получить полный каталог:

import os

def createList(foldername, fulldir = True, suffix=".jpg"):
    file_list_tmp = os.listdir(foldername)
    #print len(file_list_tmp)
    file_list = []
    if fulldir:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(os.path.join(foldername, item))
    else:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(item)
    return file_list

Ответ 30

Здесь моя универсальная функция для этого. Он возвращает список путей к файлам, а не имена файлов, так как я обнаружил, что это более полезно. Он содержит несколько дополнительных аргументов, которые делают его универсальным. Например, я часто использую его с такими аргументами, как pattern='*.txt' или subfolders=True.

import os
import fnmatch

def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
    """Return a list of the file paths matching the pattern in the specified 
    folder, optionally including files inside subfolders.
    """
    match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
    walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
    return [os.path.join(root, f)
            for root, dirnames, filenames in walked
            for f in filenames if match(f, pattern)]