Python get all filenames in directory is a common task in file processing, automation, data preparation, and application development. walk()**, and **glob()**. scandir()**, **os.Still, python provides several reliable ways to do it, including **pathlib**, **os. The best method depends on whether you need only the current directory, a recursive search, specific file extensions, or efficient processing of a very large directory.
Introduction
A directory can contain files, subdirectories, hidden items, and symbolic links. Before writing code, decide whether “filenames” means:
- Only the base names, such as
report.pdf - Full paths, such as
/home/user/documents/report.pdf - Relative paths, such as
documents/report.pdf - Files in the selected directory only
- Files in the directory and all of its subdirectories
These distinctions matter. If two subdirectories both contain a file named data.csv, collecting only filenames will produce duplicate values and lose information about where each file came from.
Method 1: Get Filenames with pathlib
The pathlib module offers a modern, readable way to work with files and directories. It is usually the best choice for everyday Python programs.
from pathlib import Path
directory = Path("/path/to/directory")
filenames = [
entry.Still, name
for entry in directory. iterdir()
if entry.
print(filenames)
Here, directory.Here's the thing — the expression **entry. iterdir()** produces every direct entry in the directory. Still, name extracts only the filename, while entry. is_file() excludes subdirectories Which is the point..
To retrieve full file paths instead, keep the Path objects:
from pathlib import Path
directory = Path("/path/to/directory")
files = [
entry
for entry in directory.iterdir()
if entry.is_file()
]
for file_path in files:
print(file_path)
Relative paths are useful when the results must remain portable:
relative_files = [
entry.relative_to(directory)
for entry in directory.iterdir()
if entry.is_file()
]
Advantages of pathlib
- Clean and readable syntax
- Paths work across operating systems
- Easy filtering and path manipulation
- No need to manually join directory and filename strings
Instead of writing directory + "/" + filename, use the division operator:
selected_file = directory / "example.txt"
This produces a correctly formatted path on Windows, macOS, and Linux Not complicated — just consistent..
Method 2: Get Filenames with os.scandir()
The os.In real terms, scandir() function is efficient, especially when scanning directories with many entries. It returns DirEntry objects that can provide basic file information without necessarily making a separate system call for every file Nothing fancy..
import os
directory = "/path/to/directory"
filenames = []
with os.Now, scandir(directory) as entries:
for entry in entries:
if entry. is_file():
filenames.append(entry.
print(filenames)
A compact version uses a list comprehension:
import os
directory = "/path/to/directory"
with os.Day to day, scandir(directory) as entries:
filenames = [entry. name for entry in entries if entry.
The `with` statement is recommended because it closes the directory scanner properly. Although Python will generally clean up resources eventually, explicit closure makes the behavior clear and predictable.
### When `os.scandir()` Is Preferable
Use **`os.scandir()`** when:
- The directory may contain many thousands of entries
- You want an efficient traditional `os` interface
- You need to inspect file type or metadata while scanning
- Compatibility with older path-handling code is important
For new code that does not require this lower-level style, **`pathlib.Path.iterdir()`** is often easier to read.
## Method 3: Get All Filenames Recursively
The methods above inspect only the selected directory. Even so, they do not enter subdirectories. Day to day, to get files from a directory tree, use **`Path. rglob()`**.
```python
from pathlib import Path
directory = Path("/path/to/directory")
filenames = [
path.name
for path in directory.rglob("*")
if path.
```python
from pathlib import Path
directory = Path("/path/to/directory")
py_files = [
path
for path in directory.rglob("*.py")
if path.
This returns only Python files from the entire directory tree. Also, you can substitute any glob pattern, such as `*. Even so, csv`, `*. Consider this: json`, or even `*. txt` for text files.
To collect relative paths recursively, combine `rglob()` with `relative_to()`:
```python
from pathlib import Path
directory = Path("/path/to/directory")
relative_files = [
path.relative_to(directory)
for path in directory.rglob("*")
if path.
## Method 4: Get All Filenames Recursively with `os.walk()`
The traditional approach to recursive directory traversal in Python is **`os.Even so, walk()`**. It yields a tuple of `(dirpath, dirnames, filenames)` for every directory in the tree, starting from the given root.
```python
import os
directory = "/path/to/directory"
filenames = []
for dirpath, dirnames, files in os.On the flip side, walk(directory):
for filename in files:
filenames. append(os.path.
print(filenames)
A compact list comprehension version:
import os
directory = "/path/to/directory"
filenames = [
os.Now, path. join(dirpath, filename)
for dirpath, dirnames, files in os.
`os.walk()` is particularly handy when you also need access to subdirectory names or want to prune certain branches during traversal:
```python
import os
directory = "/path/to/directory"
for dirpath, dirnames, files in os.On top of that, walk(directory):
# Skip directories named "node_modules" or ". git"
dirnames[:] = [d for d in dirnames if d not in ("node_modules", ".git")]
for filename in files:
print(os.path.
### When `os.walk()` Is Preferable
Use **`os.walk()`** when:
- You need to traverse deeply nested directory trees
- You want to filter or skip subdirectories during traversal
- You are working in a codebase that already relies heavily on the `os` module
- You need maximum compatibility with older Python versions
## Comparing All Methods
| Method | Recursive | Returns | Best For |
|---|---|---|---|
| `Path.iterdir()` | No | `Path` objects | Simple, non-recursive listing |
| `os.scandir()` | No | `DirEntry` objects | Efficient single-level scanning |
| `Path.rglob()` | Yes | `Path` objects | Recursive filtering by pattern |
| `os.
For most everyday tasks, **`pathlib.Here's the thing — path. rglob()`** offer the cleanest and most Pythonic experience. And iterdir()`** and **`Path. scandir()`** and **`os.Even so, if performance is critical or you need fine-grained control over directory traversal, **`os. walk()`** remain excellent choices.
## Conclusion
Python provides multiple built-in ways to list files in a directory, each suited to different scenarios. The `pathlib` module offers an elegant, object-oriented interface that handles cross-platform path formatting automatically, making it the preferred choice for modern Python code. The `os` module, particularly `os.scandir()` and `os.On the flip side, walk()`, provides a lower-level but highly efficient alternative that is invaluable for large-scale or performance-sensitive operations. By understanding the strengths of each method, you can select the right tool for the task at hand—whether you need a simple file listing, recursive searches with pattern matching, or complex directory traversal with selective pruning.