Itzik984
Itzik984

Reputation: 16794

How can I iterate over files in a given directory?

I need to iterate through all .asm files inside a given directory and do some actions on them.

How can this be done in a efficient way?

Upvotes: 945

Views: 1419686

Answers (11)

anselm
anselm

Reputation: 13671

Python 3.6 version of the above answer, using os - assuming that you have the directory path as a str object in a variable called 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

Or recursively, using 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)
  • Use rglob to replace glob('**/*.asm') with rglob('*.asm')
    • This is like calling Path.glob() with '**/' added in front of the given relative pattern:
from pathlib import Path

pathlist = Path(directory_in_str).rglob('*.asm')
for path in pathlist:
    # because path is object not string
    path_in_str = str(path)
    # print(path_in_str)

Original answer:

import os

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

Upvotes: 1302

Online User
Online User

Reputation: 17778

I don't understand why some answers are complicated. This is how I would do it with Python 2.7. Replace DIRECTORY_TO_LOOP with the directory you want to use.

import os
DIRECTORY_TO_LOOP = '/var/www/files/'
for root, dirs, files in os.walk(DIRECTORY_TO_LOOP, topdown=False):
   for name in files:
      print(os.path.join(root, name))

Upvotes: 2

crypdick
crypdick

Reputation: 19894

Since Python 3.5, things are much easier with os.scandir() and 2-20x faster (source):

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

Using scandir() instead of listdir() can significantly increase the performance of code that also needs file type or file attribute information, because os.DirEntry objects expose this information if the operating system provides it when scanning a directory. All os.DirEntry methods may perform a system call, but is_dir() and is_file() usually only require a system call for symbolic links; os.DirEntry.stat() always requires a system call on Unix but only requires one for symbolic links on Windows.

Upvotes: 106

Emmanuel Ogungbemi
Emmanuel Ogungbemi

Reputation: 79

Get all the .asm files in a directory by doing this.

import os

path = "path_to_file"
file_type = '.asm'

for filename in os.listdir(path=path):
    if filename.endswith(file_type):
        print(filename)
        print(f"{path}/{filename}")
        # do something below
  

Upvotes: 1

YAP
YAP

Reputation: 471

You can use glob for referring the directory and the list :

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)

To get the list of all directory in array you can use os :

os.listdir(directory)

Upvotes: 9

james-see
james-see

Reputation: 13206

I really like using the scandir directive that is built into the os library. Here is a working example:

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

Upvotes: 3

Doboy
Doboy

Reputation: 11112

You can try using glob module:

import glob

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

and since Python 3.5 you can search subdirectories as well:

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

From the docs:

The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell, although results are returned in arbitrary order. No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.

Upvotes: 188

Daniel McGrath
Daniel McGrath

Reputation: 474

Here's how I iterate through files in 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

NONE OF THESE TECHNIQUES GUARANTEE ANY ITERATION ORDERING

Yup, super unpredictable. Notice that I sort the filenames, which is important if the order of the files matters, i.e. for video frames or time dependent data collection. Be sure to put indices in your filenames though!

Upvotes: 15

ThorSummoner
ThorSummoner

Reputation: 18169

I'm not quite happy with this implementation yet, I wanted to have a custom constructor that does DirectoryIndex._make(next(os.walk(input_path))) such that you can just pass the path you want a file listing for. Edits welcome!

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)

Upvotes: 4

pedromateo
pedromateo

Reputation: 3135

This will iterate over all descendant files, not just the immediate children of the directory:

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)

Upvotes: 231

Greg
Greg

Reputation: 2044

Python 3.4 and later offer pathlib in the standard library. You could do:

from pathlib import Path

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

Or if you don't like list comprehensions:

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

Path objects can easily be converted to strings.

Upvotes: 28

Related Questions