Minimal runnable example
This is how I like to learn stuff:
mkdir root
cd root
mkdir \
d0 \
d1 \
d0/d0_d1
touch \
f0 \
d0/d0_f0 \
d0/d0_f1 \
d0/d0_d1/d0_d1_f0
tree
Output:
.
├── d0
│ ├── d0_d1
│ │ └── d0_d1_f0
│ ├── d0_f0
│ └── d0_f1
├── d1
└── f0
main.py
#!/usr/bin/env python3
import os
for path, dirnames, filenames in os.walk('root'):
print('{} {} {}'.format(repr(path), repr(dirnames), repr(filenames)))
Output:
'root' ['d0', 'd1'] ['f0']
'root/d0' ['d0_d1'] ['d0_f0', 'd0_f1']
'root/d0/d0_d1' [] ['d0_d1_f0']
'root/d1' [] []
This makes everything clear:
path is the root directory of each step
dirnames is a list of directory basenames in each path
filenames is a list of file basenames in each path
Tested on Ubuntu 16.04, Python 3.5.2.
Modifying dirnames changes the tree recursion
This is basically the only other thing you have to keep in mind.
E.g., if you do the following operations on dirnames, it affects the traversal:
Walk file or directory
If the input to traverse is either a file or directory, you can handle it like this:
#!/usr/bin/env python3
import os
import sys
def walk_file_or_dir(root):
if os.path.isfile(root):
dirname, basename = os.path.split(root)
yield dirname, [], [basename]
else:
for path, dirnames, filenames in os.walk(root):
yield path, dirnames, filenames
for path, dirnames, filenames in walk_file_or_dir(sys.argv[1]):
print(path, dirnames, filenames)