Processing 'every file in a folder' is one of the most common scripting tasks.
os.listdir(path=".") returns a list of the names (not full paths) of the entries in a directory, in arbitrary order. It includes hidden files such as .env but not the special entries . and ...
Because you get bare names, join them with the directory before using them:
for name in os.listdir(folder):
full = os.path.join(folder, name)To keep only files, test each one with os.path.isfile(full); for directories, os.path.isdir(full). Sort the list if you need a stable order, since the operating system makes no promise.
To match a pattern such as *.csv, either filter names with name.endswith(".csv"), use fnmatch.fnmatch(name, "*.csv"), or use the glob module: glob.glob("data/*.csv") returns matching paths (already joined), and glob.glob("**/*.py", recursive=True) searches subfolders.
os.listdir raises FileNotFoundError for a missing directory, NotADirectoryError for a file, and PermissionError when you cannot read it.
For large directories, or when you also need each entry's type or size, os.scandir is faster because it avoids an extra system call per entry. For whole trees, use os.walk.
Example
import glob
import os
os.makedirs("data/old")
for name in ["b.csv", "a.csv", "notes.txt"]:
open(os.path.join("data", name), "w").close()
print(sorted(os.listdir("data"))) # ['a.csv', 'b.csv', 'notes.txt', 'old']
files = sorted(n for n in os.listdir("data")
if os.path.isfile(os.path.join("data", n)))
print(files) # ['a.csv', 'b.csv', 'notes.txt']
print(sorted(glob.glob("data/*.csv"))) # ['data/a.csv', 'data/b.csv']
try:
os.listdir("missing")
except FileNotFoundError as e:
print(type(e).__name__) # FileNotFoundErrorRemember
os.listdirreturns bare names in arbitrary order; join and sort as needed- Filter with
os.path.isfile/isdir, or match patterns withglob - Use
scandirorwalkfor speed or recursion
Watch out for
- Calling
os.path.isfile(name)on the bare name; it is checked against the cwd, not the listed folder.