Path.iterdir

iterdir() is os.listdir() that hands you Path objects already joined to the folder. It does not recurse and the order is whatever the OS returns — sort it when order matters.

pathlib methodPython 3.4+Live demo
Common call
sorted(p for p in Path('.').iterdir() if p.is_file())
Returns
an iterator of Path objects
Replaces
os.listdir + os.path.join
Watch out
arbitrary order; not recursive (use rglob or walk)
Path.iterdir()
→ Iterator[Path]

Demo

Live evaluation
Create some files, then list one folder. Entries come back joined to the folder you listed.
Try:
Inputs
fileslist[str]files to create, comma-separated
folderstrfolder to list
Code
from pathlib import Path
for f in ['main.py', 'README.md', 'src/util.py', 'src/core.py']:
    Path(f).parent.mkdir(parents=True, exist_ok=True)
    Path(f).touch()
sorted(p.as_posix() for p in Path('.').iterdir())
Result
['README.md', 'main.py', 'src']

Listing '.' gives bare names ('src', not './src'), while listing 'src' gives 'src/util.py': each entry is the listed path joined with the name. Only one level is returned — 'src' appears as a folder, its files do not. Type a folder that does not exist and you get FileNotFoundError straight from the iterdir() call — in 3.13 the directory is read eagerly with os.scandir before any Path is returned. (The demo shows the Linux wording; Windows words the same error as [WinError 3].)

Common patterns

Only files, sorted by name
Filter with is_file(); sort because the OS order is arbitrary.
from pathlib import Path
files = sorted(p for p in Path('inbox').iterdir() if p.is_file())
Newest file in a folder
Compare modification times.
from pathlib import Path
latest = max(Path('backups').iterdir(), key=lambda p: p.stat().st_mtime)
Sub-folders only
is_dir() filters directories.
from pathlib import Path
projects = [p.name for p in Path('~/code').expanduser().iterdir() if p.is_dir()]
Check whether a folder is empty
Stop at the first entry instead of listing everything.
from pathlib import Path
is_empty = next(Path('queue').iterdir(), None) is None

Examples

1. Names in a folder
from pathlib import Path for n in ['b.txt', 'a.txt']: Path(n).touch() sorted(p.name for p in Path('.').iterdir())
Returns
['a.txt', 'b.txt']
2. Entries are joined to the folder
from pathlib import Path Path('src').mkdir() Path('src/app.py').touch() [p.as_posix() for p in Path('src').iterdir()]
Returns
['src/app.py']
3. Folders are listed, not entered
from pathlib import Path Path('pkg/sub').mkdir(parents=True) Path('pkg/sub/deep.py').touch() [p.name for p in Path('pkg').iterdir()]
Returns
['sub']
4. Only files
from pathlib import Path Path('docs').mkdir() Path('notes.md').touch() [p.name for p in Path('.').iterdir() if p.is_file()]
Returns
['notes.md']
5. Count entries
from pathlib import Path for n in ['a', 'b', 'c']: Path(n).touch() sum(1 for _ in Path('.').iterdir())
Returns
3
6. Iterating a file fails
from pathlib import Path Path('a.txt').touch() try: list(Path('a.txt').iterdir()) except OSError as e: result = type(e).__name__ result
Returns
'NotADirectoryError'

Pitfalls

1. Comparing entries with strings
iterdir() yields Path objects, and a Path never equals a str. Compare p.name or p.as_posix() — and sort, because the listing order differs between file systems.
Path == str
from pathlib import Path
Path('src').mkdir()
Path('src/app.py').touch()
'src/app.py' in list(Path('src').iterdir())
False
as_posix()
from pathlib import Path
Path('src').mkdir()
Path('src/app.py').touch()
'src/app.py' in sorted(p.as_posix() for p in Path('src').iterdir())
True
2. Expecting a recursive listing
iterdir() is one level. Use rglob("*") for everything below, or walk() for a folder-by-folder view.
iterdir
from pathlib import Path
Path('a/b').mkdir(parents=True)
Path('a/b/c.txt').touch()
sorted(p.as_posix() for p in Path('a').iterdir())
['a/b']
rglob('*')
from pathlib import Path
Path('a/b').mkdir(parents=True)
Path('a/b/c.txt').touch()
sorted(p.as_posix() for p in Path('a').rglob('*'))
['a/b', 'a/b/c.txt']
3. Forgetting that dotfiles are included
iterdir() returns every entry, hidden ones too. Filter names that start with a dot yourself.
everything
from pathlib import Path
for n in ['.env', 'app.py']:
    Path(n).touch()
sorted(p.name for p in Path('.').iterdir())
['.env', 'app.py']
skip dotfiles
from pathlib import Path
for n in ['.env', 'app.py']:
    Path(n).touch()
sorted(p.name for p in Path('.').iterdir() if not p.name.startswith('.'))
['app.py']

When to use

Use it
  • Listing one folder (files and sub-folders)
  • Cheap emptiness checks with next(…, None)
Reach for something else
  • Recursive listings → rglob / walk
  • Filtering by pattern → glob("*.csv")

Notes

CPython impl
Lib/pathlib/_local.py (3.13): collects entry.path from os.scandir(str(self)) before returning, strips a leading "./" when listing ".", and builds each Path with with_segments
Errors
FileNotFoundError for a missing folder, NotADirectoryError for a file — raised by the iterdir() call itself (3.13 scans the directory before returning)
Order
Arbitrary: whatever order the file system returns, which differs between file systems and machines — never rely on it

FAQ

[p for p in Path(folder).iterdir() if p.is_file()] for one level; Path(folder).rglob('*') for every file and folder underneath.