How can I flatten a list of lists into a single flat list?
I have a nested list structure like:
[
[1, 2, 3],
[4, 5, 6],
[7],
[8, 9]
]
What is the best way to convert this into a single flat list [1, 2, 3, 4, 5, 6, 7, 8, 9]?
Note: If your list of lists comes from a nested list comprehension, the problem can be solved more simply/directly by fixing the comprehension.
Also note: Most solutions for flattening lists only handle one level of nesting. For completely flattening deeply nested structures (recursively), different approaches are needed.
To flatten a list of lists into a single flat list, you can use several methods depending on your specific needs. For one-level nesting like your example, the most efficient and Pythonic approach is using a list comprehension: [x for sublist in nested_list for x in sublist]. For deeply nested structures, you’ll need recursive approaches or specialized libraries.
Contents
- Common Methods for One-Level Flattening
- Performance Comparison of Flattening Methods
- Recursive Flattening for Deeply Nested Structures
- Using Libraries for Complex Flattening
- Best Practices and Recommendations
Common Methods for One-Level Flattening
List Comprehension
The most efficient and Pythonic way to flatten a one-level nested list is using a list comprehension. This method is both readable and performant.
nested_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = [x for sublist in nested_list for x in sublist]
print(flat_list) # Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
As shown in the Stack Overflow research, this is actually the fastest method with benchmark results showing 143 usec per loop compared to 969 usec for the sum() approach.
Nested For Loop
A traditional nested for loop approach is more verbose but very clear and readable:
nested_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = []
for sublist in nested_list:
for element in sublist:
flat_list.append(element)
According to Python Engineer, this approach uses a for loop to iterate over the main list and another nested for loop to iterate over each element of the sublists.
Using itertools.chain
The itertools.chain method provides an efficient way to flatten lists by chaining the sublists together:
from itertools import chain
nested_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = list(chain.from_iterable(nested_list))
The Vultr documentation explains that itertools.chain provides a method called chain, which can be helpful, especially in combination with chain.from_iterable to flatten lists.
Using sum() Function
You can also use the built-in sum() function with an empty list as the starting value:
nested_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = sum(nested_list, [])
However, as noted in the Stack Overflow benchmarks, this method is significantly slower (969 usec per loop) compared to list comprehension.
Performance Comparison of Flattening Methods
Based on the research, here’s how different methods compare in performance:
| Method | Performance | Readability | Best For |
|---|---|---|---|
| List comprehension | Fastest (143 usec/loop) | High | One-level nesting, general use |
| sum() with [] | Slow (969 usec/loop) | Medium | Simple cases, avoid for large lists |
| reduce() with lambda | Very slow (1.1 msec/loop) | Low | Legacy code, avoid in new projects |
| itertools.chain() | Fast | Medium | One-level nesting, memory efficiency |
The Stack Overflow benchmarks clearly show that list comprehension is the winner for performance, while sum() and reduce() are significantly slower due to creating intermediate lists.
Recursive Flattening for Deeply Nested Structures
When dealing with arbitrarily nested lists like [1, [2, [3, 4]], [5, 6]], you need recursive approaches:
Basic Recursive Function
def flatten_recursive(nested_list):
result = []
for element in nested_list:
if isinstance(element, list):
result.extend(flatten_recursive(element))
else:
result.append(element)
return result
deeply_nested = [1, [2, [3, 4]], [5, 6]]
print(flatten_recursive(deeply_nested)) # [1, 2, 3, 4, 5, 6]
According to Finxter, recursion is a powerful tool for dealing with deeply nested lists, and custom recursive functions can handle more complex structures.
Alternative Recursive Implementation
def flatten_list(nested_list):
if not nested_list:
return []
if isinstance(nested_list[0], list):
return flatten_list(nested_list[0]) + flatten_list(nested_list[1:])
return nested_list[:1] + flatten_list(nested_list[1:])
As described in the GeeksforGeeks tutorial, this approach checks if the first element is a list and recursively processes both the first element (if it’s a list) and the rest of the list.
Handling Mixed Data Types
For lists that might contain strings or other non-list elements that shouldn’t be flattened:
def safe_flatten(nested_list):
result = []
for element in nested_list:
if isinstance(element, list):
result.extend(safe_flatten(element))
elif not isinstance(element, str): # Don't flatten strings
result.append(element)
return result
Using Libraries for Complex Flattening
more-itertools Library
For complex flattening scenarios, the more-itertools library provides specialized functions:
from more_itertools import collapse
deeply_nested = [1, [2, [3, 4]], [5, 6], "hello", ["world"]]
flat_list = list(collapse(deeply_nested))
# Control which types to flatten
flat_list_no_strings = list(collapse(deeply_nested, base_type=int))
As mentioned in the Medium guide, libraries like more-itertools and their collapse function are particularly useful for deeply nested structures.
NumPy Approach
For numerical data, NumPy provides efficient flattening:
import numpy as np
nested_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_array = np.array(nested_list).flatten().tolist()
The Medium guide also mentions converting to numpy arrays and using the flatten() method as an option.
Best Practices and Recommendations
Choose the Right Method for Your Use Case
- For one-level nesting: Use list comprehension - it’s fastest and most readable
- For deeply nested structures: Use recursive functions or more-itertools
- For large datasets: Consider memory efficiency and use generators where possible
- For mixed data types: Use safe recursive functions that handle type checking
Performance Considerations
- List comprehensions are generally the fastest for one-level flattening source
- Avoid
sum()andreduce()for flattening as they create intermediate lists - For very large lists, consider using generators instead of creating the full list in memory
Code Style Recommendations
# Best for one-level nesting
flat_list = [item for sublist in nested_list for item in sublist]
# Best for deep nesting with type safety
def flatten(nested_list, base_type=(int, float, str)):
result = []
for element in nested_list:
if isinstance(element, list):
result.extend(flatten(element, base_type))
elif not isinstance(element, str): # Don't flatten strings
result.append(element)
return result
As noted in the CodeRivers guide, understanding these methods enhances a developer’s ability to manipulate data structures effectively in Python.
Sources
- Stack Overflow - How do I make a flat list out of a list of lists?
- GeeksforGeeks - Python Program to Flatten a Nested List using Recursion
- Python Engineer - How to flatten a list of lists in Python
- Vultr Docs - Python Program to Flatten a Nested List
- Finxter - Flatten A List Of Lists In Python
- Medium - How to Flatten a List of Lists using Python: A Guide
- CodeRivers - Flattening a List in Python: Concepts, Methods, and Best Practices
Conclusion
Flattening lists of lists is a common task in Python with multiple solutions depending on your needs. For simple one-level nesting, list comprehensions offer the best combination of performance and readability. For deeply nested structures, recursive functions or specialized libraries like more-itertools provide the most robust solutions. Always consider the specific structure of your data, performance requirements, and code readability when choosing a flattening method. The most important takeaway is that list comprehensions are generally the best choice for one-level flattening, while recursive approaches are necessary for handling arbitrarily nested data structures.