Skip to Content
Course content

83: Practice Exercise: Recursive Problem Solving Drills

Click on the "Edit" button in the top corner of the screen to edit your slide content.

By now, you've got the theory of recursion down: a base case to stop the bleeding and a recursive step to move toward that base. But there's a huge gap between understanding that concept and actually staring at a blank screen trying to figure out how to break a problem down. To bridge that gap, I want to walk you through how I'd approach a common real-world headache: flattening a deeply nested list.

Dealing with the "Nested List" Nightmare

Imagine you're scraping data or parsing a weird JSON file, and you end up with a list like this: [1, [2, [3, 4], 5], 6, [7, 8]]. You just want a simple, flat list of integers. You could try a for loop, but you don't know how deep the nesting goes. This is where recursion shines because the function doesn't need to know the depth; it just needs to know how to handle one level at a time.

Mapping out the Recursive Path

My mental model here is simple: I'll iterate through the list. If I hit an element that is itself a list, I'll tell the function to "go inside" that list and do the same thing. If I hit something that isn't a list, I've hit my base case—it's just a value I can collect.

def flatten_list(nested_data):
    flat = []
    for item in nested_data:
        if isinstance(item, list):
            # This is the recursive call
            flat.append(flatten_list(item))
        else:
            flat.append(item)
    return flat

Where I messed up the aggregation

I'll be honest—I've written the snippet above more times than I'd like to admit before realizing it's wrong. If you run that code with [1, [2, 3]], you won't get [1, 2, 3]. You'll get [1, [2, 3]]. Wait, that's exactly what we started with!

Here is the mistake: I used .append() on the result of the recursive call. Since flatten_list(item) returns a list, .append() just puts that entire list inside my flat list as a single element. I'm essentially just rebuilding the nesting I was trying to destroy. I forgot that the result of a recursive call on a list is still a list.

Cleaning up the final logic

To fix this, I need to merge the returned list into my current list rather than nesting it. In Python, .extend() is the tool for this. It takes the elements out of the provided list and adds them individually.

def flatten_list(nested_data):
    flat = []
    for item in nested_data:
        if isinstance(item, list):
            # Use extend instead of append to merge the results
            flat.extend(flatten_list(item))
        else:
            flat.append(item)
    return flat

# Testing it out
nested = [1, [2, [3, 4], 5], 6, [7, 8]]
print(flatten_list(nested)) # Output: [1, 2, 3, 4, 5, 6, 7, 8]

Now the logic holds. The function dives as deep as necessary, and as it "bubbles back up" the recursion stack, it carries those values back and extends them into the higher-level lists. It's a clean, elegant way to handle unpredictable depth without writing twenty nested while loops.




📋 Practical Task

Exercise: Deep-Cleaning a Nested Directory Structure

In this exercise, you'll apply the same recursive logic we used for lists to a dictionary. This simulates how a file system works (folders containing files or other folders).

You are given a dictionary representing a folder structure. Some keys map to strings (files), and others map to dictionaries (sub-folders). Your task is to write a recursive function called list_all_files(folder_structure) that returns a single flat list of all the file names found at any depth.

Starting Data:

folder_structure = {
    "Documents": {
        "Resume.pdf": "file",
        "Work": {
            "Project_A.docx": "file",
            "Project_B.docx": "file",
            "Archive": {
                "Old_Notes.txt": "file"
            }
        },
        "Budget.xlsx": "file"
    },
    "Photos": {
        "Vacation.jpg": "file",
        "Family": {
            "Mom.png": "file",
            "Dad.png": "file"
        }
    },
    "todo.txt": "file"
}

Requirements:

  • Your function must handle an arbitrary number of nested folders.
  • The final output should be a flat list of strings: ['Resume.pdf', 'Project_A.docx', 'Project_B.docx', 'Old_Notes.txt', 'Budget.xlsx', 'Vacation.jpg', 'Mom.png', 'Dad.png', 'todo.txt'] (Order does not matter).
  • Avoid using any external libraries; stick to standard dictionary iteration.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.