Jak mogę iterować pliki w danym katalogu?


555

Muszę iterować wszystkie .asmpliki w danym katalogu i wykonywać na nich pewne działania.

Jak można to zrobić w efektywny sposób?

Odpowiedzi:


807

Oryginalna odpowiedź:

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

Wersja powyższej odpowiedzi w języku Python 3.6, używając os- zakładając, że ścieżka katalogu jest strobiektem w zmiennej o nazwie 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

Lub rekurencyjnie, używając 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
Wygląda na to, że wyświetla katalogi lub pliki bezpośrednio w katalogu. Odpowiedź pedromateo poniżej wydaje się zawierać listę rekurencyjną.
Jay Sheth,

8
Należy pamiętać, że w katalogu Python 3.6 oczekuje się, że będzie w bajtach, a następnie listdir wypluje listę nazw plików również w bajtach typu danych, więc nie można uruchamiać na nim bezpośrednio końcówek. Ten blok kodu należy zmienić nadirectory = 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
Kim Stacks,

13
print(os.path.join(directory, filename))należy go zmienić print(os.path.join(directory_in_str, filename)), aby działał w Pythonie 3.6
Hugo Koopmans,

54
Jeśli widzisz to w 2017 roku lub później, os.scandir (dir_str) jest już dostępny i znacznie prostszy w użyciu. Nie potrzeba kodu fsen. for entry in os.scandir(path): print(entry.path)
koza

2
Wolę if filename.endswith((".asm", ".py")):, abyif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio

151

Spowoduje to iterację wszystkich plików potomnych, nie tylko bezpośrednich potomków katalogu:

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)

3
Odwołanie do funkcji os.walk znajduje się pod następującym adresem
ScottMcC

136

Możesz spróbować użyć modułu glob :

import glob

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

a od Python 3.5 możesz również przeszukiwać podkatalogi:

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

Z dokumentów:

Moduł glob znajduje wszystkie nazwy ścieżek pasujące do określonego wzorca zgodnie z regułami używanymi przez powłokę uniksową, chociaż wyniki są zwracane w dowolnej kolejności. Nie jest wykonywane rozwinięcie tyldy, ale *,? I zakresy znaków wyrażone za pomocą [] będą poprawnie dopasowane.


19

Od wersji Python 3.5 rzeczy są znacznie łatwiejsze dzięki 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)

Użycie scandir () zamiast listdir () może znacznie zwiększyć wydajność kodu, który również potrzebuje informacji o typie pliku lub atrybucie pliku, ponieważ obiekty os.DirEntry ujawniają te informacje, jeśli system operacyjny udostępnia je podczas skanowania katalogu. Wszystkie metody os.DirEntry mogą wykonywać wywołanie systemowe, ale is_dir () i is_file () zwykle wymagają tylko wywołania systemowego dla dowiązań symbolicznych; os.DirEntry.stat () zawsze wymaga wywołania systemowego w systemie Unix, ale wymaga tylko jednego dla dowiązań symbolicznych w systemie Windows.


entryjest posix.DirEntry typu z wieloma przydatnych metod, takich jak entry.is_dir(), is_file(),is_symlink()
crypdick

17

Python 3.4 i nowsze wersje oferują pathlib w standardowej bibliotece. Mógłbyś:

from pathlib import Path

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

Lub jeśli nie lubisz wyrażeń z listy:

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

Path obiekty można łatwo konwertować na ciągi.


9

Oto jak iteruję pliki w Pythonie:

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

ŻADNA Z TEJ TECHNIKI NIE GWARANTUJE ŻADNEGO ZAMÓWIENIA ITERACYJNEGO

Tak, super nieprzewidywalny. Zauważ, że sortuję nazwy plików, co jest ważne, jeśli kolejność plików ma znaczenie, tj. Dla ramek wideo lub gromadzenia danych zależnych od czasu. Pamiętaj jednak o umieszczeniu indeksów w nazwach plików!


Nie zawsze posortowane ... im1, im10, im11 ..., im2 ... W przeciwnym razie przydatne podejście. from pkg_resources import parse_versioni filenames.sort(key=parse_version)zrobił to.
Hastur

5

Możesz użyć glob do odwołania się do katalogu i listy:

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)

Aby uzyskać listę wszystkich katalogów w tablicy, możesz użyć os :

os.listdir(directory)

4

Nie jestem jeszcze do końca zadowolony z tej implementacji. Chciałem mieć niestandardowego konstruktora, który robi DirectoryIndex._make(next(os.walk(input_path)))takie, że możesz po prostu podać ścieżkę, dla której chcesz mieć listę plików. Mile widziane zmiany!

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)

2

Naprawdę lubię korzystać z scandirdyrektywy wbudowanej w osbibliotekę. Oto działający przykład:

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

zduplikowana odpowiedź
crypdick
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.