Python
directory listing
os module
programming
code tutorial

How can I list the contents of a directory in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Listing directory contents is fundamental in Python scripts for ETL jobs, file management, and automation tooling. Python offers multiple APIs: os.listdir, os.scandir, and pathlib.Path.iterdir, each with different ergonomics and performance.

This article shows practical choices and safe handling patterns.

Core Sections

1) Basic listing with os.listdir

python
1import os
2
3entries = os.listdir("/tmp")
4print(entries)

Returns names only (not full paths) and includes files and directories.

2) Efficient metadata access with os.scandir

python
1import os
2
3with os.scandir("/tmp") as it:
4    for entry in it:
5        if entry.is_file():
6            print("file", entry.name)

scandir is often faster when you also need file-type checks.

3) Modern style with pathlib

python
1from pathlib import Path
2
3for p in Path("/tmp").iterdir():
4    print(p.name, "dir" if p.is_dir() else "file")

pathlib improves readability in path-heavy codebases.

4) Recursive listing

python
1from pathlib import Path
2
3for p in Path("/tmp").rglob("*.log"):
4    print(p)

Use cautiously on large trees to avoid expensive scans.

5) Error handling

python
1from pathlib import Path
2
3try:
4    items = list(Path("/restricted").iterdir())
5except PermissionError:
6    items = []

Always handle missing paths and permission failures in automation.

6) Production checklist for Python directory traversal

Code examples are necessary, but production readiness depends on how this pattern behaves under failure, load, and operational drift. Before rollout, define success criteria that are measurable. A useful baseline is three metrics: correctness (for example, expected output match rate), reliability (error rate and retry behavior), and latency (p95 or p99 execution time). Capture these metrics in a repeatable test environment rather than relying on ad hoc local runs. If external systems are involved, include at least one synthetic fault scenario such as timeout, malformed payload, or temporary dependency outage. This confirms the implementation fails predictably and recovers in a controlled way.

Document environment assumptions close to the code. Include runtime version constraints, required environment variables, and exact dependency versions used during validation. Many regressions come from mismatched environments rather than algorithmic changes. A short README snippet or inline comment that names these assumptions can prevent repeated troubleshooting later. Also define ownership for operational issues: who receives alerts, what threshold triggers action, and what rollback path is acceptable. Without explicit ownership and rollback criteria, otherwise small incidents can take longer to resolve.

A practical rollout sequence is:

  1. Run automated checks (lint, unit tests, static validation) in CI.
  2. Execute a smoke test against representative input sizes.
  3. Validate one failure mode and verify error visibility in logs.
  4. Deploy behind a feature flag or phased rollout if possible.
  5. Monitor key metrics for a defined stabilization window.
bash
1# Example operator workflow
2make lint
3make test
4./scripts/smoke_check.sh

Finally, keep a short limitations section. State what the current approach intentionally does not optimize or support. This prevents accidental misuse by future contributors and keeps design discussions grounded in explicit tradeoffs. For long-lived systems, schedule periodic review of this implementation, especially after runtime upgrades or library changes. A lightweight maintenance cadence often catches compatibility issues before they become production incidents.

Common Pitfalls

  • Assuming os.listdir returns full paths.
  • Recursing entire filesystems unintentionally with broad glob patterns.
  • Ignoring permission and race-condition errors during scans.
  • Mixing string and Path APIs inconsistently.
  • Performing unnecessary metadata calls in large directories.

Summary

Choose directory listing API based on needs: listdir for simple names, scandir for efficient metadata checks, and pathlib for maintainable path logic. Add robust error handling and controlled recursion to keep file-processing scripts reliable.

A short maintenance note should accompany this implementation in your repository docs so future contributors know expected behavior, validation steps, and rollback options. That small documentation investment usually prevents repeat regressions during dependency upgrades, framework changes, and environment migrations.


Course illustration
Course illustration

All Rights Reserved.