Stop Fighting Nested Lists: Here's How to Flatten Them in Python
Learn practical ways to flatten nested lists in Python, from simple list comprehensions to recursive functions and production-ready libraries like more-itertools.
Advertisement
If you've ever worked with data that comes from APIs, JSON files, or user input, you've probably run into nested lists. You know, those lists inside lists inside lists that make your code look like a Russian nesting doll. Flattening them is one of those tasks that seems simple until you actually try to do it.
Let me show you the practical ways to flatten nested lists in Python, from the dead-simple to the more robust approaches.
The Problem We're Solving
Imagine you have data like this:
nested = [[1, 2], [3, 4, 5], [6], [7, 8, 9]]
You want to turn it into:
flat = [1, 2, 3, 4, 5, 6, 7, 8, 9]
That's the basic case. But what about deeper nesting? Like [[[1, 2], [3]], [4, [5, 6]]]? That's where things get interesting.
Method 1: The Simple List Comprehension (For One Level of Nesting)
If your list only has one level of nesting, this is the cleanest approach:
nested = [[1, 2], [3, 4, 5], [6], [7, 8, 9]]
flat = [item for sublist in nested for item in sublist]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
The double for loop inside the comprehension might look confusing at first, but read it like this: "For each sublist in the nested list, for each item in that sublist, add the item to the new list." It's Python's way of being concise without sacrificing readability.
Method 2: The itertools.chain Approach (For One Level)
If you're already using itertools in your project, this is a clean option:
from itertools import chain
nested = [[1, 2], [3, 4, 5], [6], [7, 8, 9]]
flat = list(chain.from_iterable(nested))
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
chain.from_iterable takes each sublist and chains them together into a single iterator. It's efficient because it doesn't create intermediate lists. But it only works for one level of nesting.
Method 3: The Recursive Approach (For Deeply Nested Lists)
When you have lists inside lists inside lists, you need recursion. Here's a clean recursive function:
def flatten_deep(nested_list):
result = []
for item in nested_list:
if isinstance(item, list):
result.extend(flatten_deep(item))
else:
result.append(item)
return result
deep_nested = [[1, [2, 3]], [4, [5, [6, 7]]], 8]
flat = flatten_deep(deep_nested)
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8]
The function checks each item. If it's a list, it calls itself recursively. If it's not, it adds the item to the result. This handles any depth of nesting.
Method 4: The Generator Version (Memory Efficient)
If you're working with large datasets, you don't want to build the entire flattened list in memory at once. Use a generator instead:
def flatten_generator(nested_list):
for item in nested_list:
if isinstance(item, list):
yield from flatten_generator(item)
else:
yield item
nested = [[1, 2], [3, [4, 5]], 6]
flat = list(flatten_generator(nested))
print(flat) # [1, 2, 3, 4, 5, 6]
The yield from syntax is Python 3.3+ and makes recursive generators much cleaner. This approach is memory-efficient because it yields items one at a time instead of building the entire list at once.
Method 5: The One-Liner (For the Brave)
If you want to impress your coworkers at PythonSkillset, here's a recursive one-liner:
flatten = lambda lst: [item for sublist in lst for item in (flatten(sublist) if isinstance(sublist, list) else [sublist])]
But honestly? Don't use this in production code. It's hard to read and debug. Save it for code golf or impressing people at meetups.
Method 6: Handling Mixed Types (Strings and Numbers)
Here's a real-world scenario: you have a list that contains both strings and nested lists. The isinstance check works fine, but be careful with strings — they're iterable in Python, so isinstance("hello", list) returns False, which is what we want. But if you have strings inside lists, they'll be treated as single items, not iterables to flatten further.
def flatten_mixed(nested_list):
result = []
for item in nested_list:
if isinstance(item, list):
result.extend(flatten_mixed(item))
else:
result.append(item)
return result
mixed = [["hello", "world"], [1, [2, 3]], "single"]
flat = flatten_mixed(mixed)
print(flat) # ['hello', 'world', 1, 2, 3, 'single']
Method 5: The more-itertools Library (Production Ready)
If you're working on a real project at PythonSkillset and don't want to reinvent the wheel, install the more-itertools package:
pip install more-itertools
Then use collapse:
from more_itertools import collapse
nested = [[1, 2], [3, [4, 5]], 6]
flat = list(collapse(nested))
print(flat) # [1, 2, 3, 4, 5, 6]
collapse handles arbitrary nesting and even lets you control the depth with the levels parameter. It's battle-tested and handles edge cases like empty lists gracefully.
Which One Should You Use?
Here's my rule of thumb:
- One level of nesting: Use the list comprehension. It's fast and readable.
- Deep nesting but small data: Use the recursive function. It's clear and easy to debug.
- Large datasets: Use the generator version. Memory efficiency matters.
- Production code: Use
more-itertools.collapse. It's been tested by thousands of developers and handles edge cases you haven't thought of yet.
A Real-World Example
At PythonSkillset, we recently had to flatten a nested list of user permissions from an API response. The data looked like this:
permissions = [
["read", "write"],
["delete", ["admin_read", "admin_write"]],
"view_analytics"
]
Using the recursive approach, we flattened it to a simple list of permission strings, which made it easy to check if a user had a specific permission:
def has_permission(user_permissions, target):
flat = flatten_deep(user_permissions)
return target in flat
Simple, clean, and it works for any depth of nesting.
The Takeaway
Flattening nested lists in Python doesn't have to be complicated. Start with the list comprehension for simple cases, use recursion for deep nesting, and reach for more-itertools when you need something production-ready. The key is matching the approach to your specific data structure and performance needs.
What's your go-to method for flattening lists? Drop a comment below and let us know how you handle this in your projects.
Advertisement
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.