Làm thế nào tôi có thể lặp lại các tập tin trong một thư mục nhất định?


555

Tôi cần lặp lại tất cả .asmcác tệp trong một thư mục nhất định và thực hiện một số hành động trên chúng.

Làm thế nào điều này có thể được thực hiện một cách hiệu quả?

Câu trả lời:


807

Câu trả lời gốc:

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

Phiên bản Python 3.6 của câu trả lời trên, sử dụng os- giả sử rằng bạn có đường dẫn thư mục dưới dạng một strđối tượng trong một biến có tên 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

Hoặc đệ quy, sử dụng 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
Điều này dường như chỉ liệt kê các thư mục hoặc tập tin ngay dưới một thư mục. Câu trả lời của pedromateo dưới đây dường như thực hiện một danh sách đệ quy.
Jay Sheth

8
Xin lưu ý rằng trong thư mục Python 3.6 được dự kiến ​​là byte và sau đó listdir sẽ đưa ra một danh sách tên tệp theo kiểu dữ liệu byte để bạn không thể chạy endswith trực tiếp trên nó. Khối mã này nên được đổi thànhdirectory = 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))cần phải được thay đổi để làm print(os.path.join(directory_in_str, filename))cho nó hoạt động trong python 3.6
Hugo Koopmans

54
Nếu bạn thấy điều này trong năm 2017 hoặc hơn thế nữa, os.scandir (dir_str) hiện có sẵn và dễ sử dụng hơn nhiều. Không cần fsencode. for entry in os.scandir(path): print(entry.path)

2
Thích if filename.endswith((".asm", ".py")):đếnif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio

152

Điều này sẽ lặp đi lặp lại trên tất cả các tập tin con cháu, không chỉ là con ngay lập tức của thư mục:

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
Một tài liệu tham khảo cho các chức năng os.walk được tìm thấy ở những điều sau đây: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC

136

Bạn có thể thử sử dụng mô-đun toàn cầu :

import glob

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

và kể từ Python 3.5, bạn cũng có thể tìm kiếm các thư mục con:

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

Từ các tài liệu:

Mô-đun toàn cầu tìm thấy tất cả các tên đường dẫn khớp với một mẫu đã chỉ định theo các quy tắc được sử dụng bởi trình bao Unix, mặc dù các kết quả được trả về theo thứ tự tùy ý. Không có mở rộng dấu ngã được thực hiện, nhưng *,?, Và phạm vi ký tự được biểu thị bằng [] sẽ được khớp chính xác.


19

Kể từ Python 3.5, mọi thứ dễ dàng hơn nhiều với 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)

Sử dụng scandir () thay cho listdir () có thể làm tăng đáng kể hiệu năng của mã cũng cần thông tin thuộc tính loại tệp hoặc thuộc tính tệp, vì các đối tượng os.DirEntry lộ thông tin này nếu hệ điều hành cung cấp nó khi quét thư mục. Tất cả các phương thức os.DirEntry có thể thực hiện một cuộc gọi hệ thống, nhưng is_dir () và is_file () thường chỉ yêu cầu một cuộc gọi hệ thống cho các liên kết tượng trưng; os.DirEntry.stat () luôn yêu cầu một cuộc gọi hệ thống trên Unix nhưng chỉ yêu cầu một liên kết tượng trưng trên Windows.


entrylà một posix.DirEntry loại với một loạt các phương pháp tiện dụng như entry.is_dir(), is_file(),is_symlink()
crypdick

17

Python 3,4 trở lên cung cấp pathlib trong thư viện chuẩn. Bạn có thể làm:

from pathlib import Path

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

Hoặc nếu bạn không thích cách hiểu danh sách:

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

Path các đối tượng có thể dễ dàng được chuyển đổi thành chuỗi.


9

Đây là cách tôi lặp qua các tệp trong 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

KHÔNG CÓ KỸ THUẬT NÀY ĐẢM BẢO BẤT K OR ĐẶT HÀNG NÀO

Yup, siêu khó lường. Lưu ý rằng tôi sắp xếp tên tệp, điều này rất quan trọng nếu thứ tự của các tệp quan trọng, tức là đối với khung video hoặc thu thập dữ liệu phụ thuộc thời gian. Hãy chắc chắn để đặt các chỉ số trong tên tập tin của bạn mặc dù!


Không phải lúc nào cũng được sắp xếp ... im1, im10, im11 ..., im2 ... Nếu không thì cách tiếp cận hữu ích. from pkg_resources import parse_versionfilenames.sort(key=parse_version)đã làm nó.
Hastur

5

Bạn có thể sử dụng global để giới thiệu thư mục và danh sách:

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)

Để có được danh sách tất cả các thư mục trong mảng, bạn có thể sử dụng os :

os.listdir(directory)

4

Tôi không hoàn toàn hài lòng với việc triển khai này, tôi muốn có một hàm tạo tùy chỉnh DirectoryIndex._make(next(os.walk(input_path)))để bạn có thể vượt qua đường dẫn mà bạn muốn liệt kê tệp. Chỉnh sửa chào mừng!

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

Tôi thực sự thích sử dụng scandirchỉ thị được tích hợp trong osthư viện. Dưới đây là một ví dụ hoạt động:

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

câu trả lời trùng lặp
crypdick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.