Как я могу перебирать файлы в данном каталоге?

556

Мне нужно перебрать все .asmфайлы в данном каталоге и выполнить с ними некоторые действия.

Как это можно сделать эффективным способом?

Itzik984
источник

Ответы:

808

Оригинальный ответ:

import os

for filename in os.listdir(directory):
    if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
        continue
    else:
        continue

Python 3.6 версия вышеупомянутого ответа, используя os- при условии, что у вас есть путь к каталогу как strобъект в переменной с именем directory_in_str:

import os

directory = os.fsencode(directory_in_str)

for file in os.listdir(directory):
     filename = os.fsdecode(file)
     if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
         continue
     else:
         continue

Или рекурсивно, используя pathlib:

from pathlib import Path

pathlist = Path(directory_in_str).glob('**/*.asm')
for path in pathlist:
     # because path is object not string
     path_in_str = str(path)
     # print(path_in_str)
Ансельм
источник
1
Похоже, это просто перечисляет каталоги или файлы непосредственно в каталоге. Ответ от pedromateo ниже, кажется, делает рекурсивный список.
Джей Шет
8
Обратите внимание, что в Python 3.6 каталог, как ожидается, будет в байтах, а затем listdir будет выдавать список имен файлов также в байтовом типе данных, поэтому вы не можете запускать заканчивается с ним напрямую. Этот блок кода должен быть изменен наdirectory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
Ким Стеки
13
print(os.path.join(directory, filename))нужно изменить, чтобы print(os.path.join(directory_in_str, filename))заставить его работать в python 3.6
Хьюго Купманс
54
Если вы видите это в 2017 году или позже, os.scandir (dir_str) теперь доступен и намного удобнее в использовании. Нет необходимости в fsencode. for entry in os.scandir(path): print(entry.path)
коза
2
Предпочитаю , if filename.endswith((".asm", ".py")):чтобыif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio
153

Это будет повторять все файлы-потомки, а не только непосредственные дочерние элементы каталога:

import os

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        #print os.path.join(subdir, file)
        filepath = subdir + os.sep + file

        if filepath.endswith(".asm"):
            print (filepath)
pedromateo
источник
3
Ссылка на функцию os.walk находится по следующему адресу: адресу docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC
136

Вы можете попробовать использовать модуль glob :

import glob

for filepath in glob.iglob('my_dir/*.asm'):
    print(filepath)

и начиная с Python 3.5 вы также можете искать в подкаталогах:

glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']

Из документов:

Модуль glob находит все пути, соответствующие указанному шаблону, в соответствии с правилами, используемыми оболочкой Unix, хотя результаты возвращаются в произвольном порядке. Расширение тильды не выполняется, но *,? И диапазоны символов, выраженные [], будут правильно сопоставлены.

Doboy
источник
19

Начиная с Python 3.5, с os.scandir ( ) все намного проще

with os.scandir(path) as it:
    for entry in it:
        if entry.name.endswith(".asm") and entry.is_file():
            print(entry.name, entry.path)

Использование scandir () вместо listdir () может значительно повысить производительность кода, который также нуждается в информации о типе файла или атрибуте файла, поскольку объекты os.DirEntry предоставляют эту информацию, если операционная система предоставляет ее при сканировании каталога. Все методы os.DirEntry могут выполнять системный вызов, но для is_dir () и is_file () обычно требуется только системный вызов для символических ссылок; os.DirEntry.stat () всегда требует системного вызова в Unix, но требует только одного для символических ссылок в Windows.

crypdick
источник
entryявляется posix.DirEntry типа с кучей удобных методов , таких как entry.is_dir(), is_file(),is_symlink()
crypdick
17

Python 3.4 и более поздние версии предлагают pathlib в стандартной библиотеке. Вы могли бы сделать:

from pathlib import Path

asm_pths = [pth for pth in Path.cwd().iterdir()
            if pth.suffix == '.asm']

Или, если вам не нравятся списки:

asm_paths = []
for pth in Path.cwd().iterdir():
    if pth.suffix == '.asm':
        asm_pths.append(pth)

Path объекты могут быть легко преобразованы в строки.

Greg
источник
9

Вот как я перебираю файлы в Python:

import os

path = 'the/name/of/your/path'

folder = os.fsencode(path)

filenames = []

for file in os.listdir(folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
        filenames.append(filename)

filenames.sort() # now you have the filenames and can do something with them

НИКАКАЯ ИЗ ЭТИХ ТЕХНИК НЕ ГАРАНТИРУЕТ НИКАКОГО ЗАКАЗА Итераций

Да супер непредсказуемо. Обратите внимание, что я сортирую имена файлов, что важно, если порядок файлов имеет значение, т.е. для видеокадров или сбора данных, зависящих от времени. Не забудьте поставить индексы в ваших именах файлов, хотя!

Дэниел МакГрат
источник
Не всегда сортируются ... im1, im10, im11 ..., im2 ... В противном случае полезный подход. from pkg_resources import parse_versionи filenames.sort(key=parse_version)сделал это.
Гастур
5

Вы можете использовать glob для ссылки на каталог и список:

import glob
import os

#to get the current working directory name
cwd = os.getcwd()
#Load the images from images folder.
for f in glob.glob('images\*.jpg'):   
    dir_name = get_dir_name(f)
    image_file_name = dir_name + '.jpg'
    #To print the file name with path (path will be in string)
    print (image_file_name)

Чтобы получить список всех каталогов в массиве, вы можете использовать os :

os.listdir(directory)
ПЕА
источник
4

Я еще не совсем доволен этой реализацией, я хотел иметь собственный конструктор, который бы делал так DirectoryIndex._make(next(os.walk(input_path))), чтобы вы могли просто передать путь, для которого вы хотите получить список файлов. Редактирование приветствуется!

import collections
import os

DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])

for file_name in DirectoryIndex(*next(os.walk('.'))).files:
    file_path = os.path.join(path, file_name)
ThorSummoner
источник
2

Мне действительно нравится использовать scandirдирективу, встроенную в osбиблиотеку. Вот рабочий пример:

import os

i = 0
with os.scandir('/usr/local/bin') as root_dir:
    for path in root_dir:
        if path.is_file():
            i += 1
            print(f"Full path is: {path} and just the name is: {path.name}")
print(f"{i} files scanned successfully.")
jamescampbell
источник
двойной