Card 04/ 08
Recursion Example: Counting Files in Nested Folders
A folder holds files and folders, so the count of a folder is a recursive sum.
Counting the files under a folder is recursion over a structure rather than over a number: a folder holds files and more folders, so the count for a folder is its own files plus the count for each folder inside it. This card covers that count on a small photo archive, and where its base case, the input answered without a further call, hides.
The archive is a folder called photos holding a readme and two folders, one per year, with three pictures between them. Seven entries in all, four of them files. The figure shows the archive, and the note beside each folder is the number its call returned in a run.
photos/, returns 4: its 1 file, plus 2, plus 1
readme.txt
2024/, returns 2
beach.jpg
hills.jpg
2025/, returns 1
snow.jpg
The function follows the description of a folder line for line. It starts the total at the number of files the folder holds directly, then adds the count for each folder inside, and the highlighted line is the recursive call. It prints each result as its call returns.
class Folder:
def __init__(self, name, files, folders):
self.name = name
self.files = files
self.folders = folders
def count_files(folder):
total = len(folder.files)
for inner in folder.folders:
total += count_files(inner)
print(f"count_files({folder.name}) returns {total}")
return total
photos = Folder(
"photos/",
["readme.txt"],
[
Folder("2024/", ["beach.jpg", "hills.jpg"], []),
Folder("2025/", ["snow.jpg"], []),
],
)
count_files(photos)count_files(2024/) returns 2
count_files(2025/) returns 1
count_files(photos/) returns 4The output runs from the inside out. count_files(photos/) is called first but returns last, because it cannot add 2 and 1 to its own 1 until both calls inside it have returned them.
There is no if for a base case here, yet there is one: a folder with no folders inside it. For 2024/ and 2025/ the loop runs zero times, no further call is made, and the count is their files alone. Every call is on a folder one level deeper than its caller's, so the calls reach such a folder on every path.
The same shape appears whenever a thing is defined in terms of smaller things of its own kind: a comment with replies that have replies, a menu with submenus, a list holding lists. Name what the thing holds directly, recurse into the parts that are the same kind of thing, and add up.
← → move through sections and cards