What is the Python way to walk a directory tree?
os.walk
and os.scandir
are great options, however, I've been using pathlib more and more, and with pathlib you can use the .glob()
method:
root_directory = Path(".")
for path_object in root_directory.glob('**/*'):
if path_object.is_file():
print(f"hi, I'm a file: {path_object}")
elif path_object.is_dir():
print(f"hi, I'm a dir: {path_object}")
Indeed using
items += [item]
is bad for many reasons...
The
append
method has been made exactly for that (appending one element to the end of a list)You are creating a temporary list of one element just to throw it away. While raw speed should not your first concern when using Python (otherwise you're using the wrong language) still wasting speed for no reason doesn't seem the right thing.
You are using a little asymmetry of the Python language... for list objects writing
a += b
is not the same as writinga = a + b
because the former modifies the object in place, while the second instead allocates a new list and this can have a different semantic if the objecta
is also reachable using other ways. In your specific code this doesn't seem the case but it could become a problem later when someone else (or yourself in a few years, that is the same) will have to modify the code. Python even has a methodextend
with a less subtle syntax that is specifically made to handle the case in which you want to modify in place a list object by adding at the end the elements of another list.
Also as other have noted seems that your code is trying to do what os.walk
already does...
For anyone looking for a solution using pathlib
(python >= 3.4
)
from pathlib import Path
def walk(path):
for p in Path(path).iterdir():
if p.is_dir():
yield from walk(p)
continue
yield p.resolve()
# recursively traverse all files from current directory
for p in walk(Path('.')):
print(p)
# the function returns a generator so if you need a list you need to build one
all_files = list(walk(Path('.')))
However, as mentioned above, this does not preserve the top-down ordering given by os.walk
Take a look at the os.walk
function which returns the path along with the directories and files it contains. That should considerably shorten your solution.