Skip to main content

How to Flatten a List of Lists in Python

Flattening a list of lists means converting a nested list structure into a single, one-dimensional list. This is a common operation when processing data from APIs, databases, or file parsers that return grouped results, and you need everything in a simpler, flat format for analysis or further processing.

For example:

  • Input: [[1, 2, 3], [4, 5], [6, 7]]
  • Output: [1, 2, 3, 4, 5, 6, 7]

Python offers several ways to accomplish this. This guide covers each approach (from the most efficient to the most straightforward) so you can pick the right one for your situation.

The itertools module provides chain.from_iterable(), which is the most efficient and idiomatic way to flatten a list of lists in Python. It creates a single iterator that lazily yields elements from each sublist without creating intermediate lists.

import itertools

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = list(itertools.chain.from_iterable(nested))

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]

Since chain.from_iterable() returns an iterator, it's memory-efficient for large datasets - elements are produced on demand rather than all at once.

tip

If you don't need a list and just want to iterate over the flattened elements (e.g., in a for loop), skip the list() conversion to save memory:

for item in itertools.chain.from_iterable(nested):
print(item, end=" ")
# Output: 1 2 3 4 5 6 7

Using List Comprehension​

List comprehension is a concise and Pythonic approach that most Python developers are comfortable reading. It uses a nested for expression to iterate over each sublist and then each item within it.

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = [item for sublist in nested for item in sublist]

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]
Reading order of nested comprehensions

The nested for clauses read left to right, matching the order of equivalent nested for loops:

# This list comprehension:
flat = [item for sublist in nested for item in sublist]

# Is equivalent to:
flat = []
for sublist in nested:
for item in sublist:
flat.append(item)

Using a for Loop​

The most explicit and beginner-friendly approach uses a standard nested for loop. While more verbose, it's easy to understand and allows you to add custom logic during the flattening process.

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = []
for sublist in nested:
for item in sublist:
flat.append(item)

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]

You can also use the extend() method to append all items from a sublist at once, which is slightly more efficient than calling append() repeatedly:

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = []
for sublist in nested:
flat.extend(sublist)

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]

Using functools.reduce()​

The reduce() function from the functools module applies a function cumulatively to the items of an iterable. For flattening, it concatenates each sublist to an accumulator list.

from functools import reduce

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = reduce(lambda acc, sublist: acc + sublist, nested)

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]

You can also use the operator.concat function instead of a lambda for cleaner code:

from functools import reduce
import operator

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = reduce(operator.concat, nested)

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]
Performance concern with reduce() and sum()

Both reduce() with list concatenation and sum() (covered below) create a new intermediate list at every step. For a list with n sublists, this results in O(n²) time complexity because each concatenation copies all previously accumulated elements.

For small lists this is fine, but for large datasets, prefer itertools.chain.from_iterable() or list comprehension, which operate in O(n) time.

Using sum() with an Empty List​

A clever trick is using Python's sum() function with an empty list [] as the start value. Since sum() uses the + operator, and + concatenates lists, this effectively flattens the structure.

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = sum(nested, [])

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]

While this is a concise one-liner, it shares the same O(n²) performance issue as reduce() because it creates intermediate lists at each step. Use it only for small datasets.

Using numpy.concatenate() (For Numeric Data)​

If you're already working with numeric data and have NumPy installed, numpy.concatenate() provides a highly optimized flattening operation:

import numpy as np

nested = [[1, 2, 3], [4, 5], [6, 7]]

flat = np.concatenate(nested).tolist()

print(flat)

Output:

[1, 2, 3, 4, 5, 6, 7]
note

This approach works best with numeric data. If your sublists contain strings or mixed types, stick with the pure Python methods. Also, importing NumPy solely for flattening is overkill - use this when NumPy is already part of your project.

Handling Deeply Nested Lists​

All the methods above handle one level of nesting. If you have irregularly or deeply nested lists (e.g., [1, [2, [3, [4]]]]), you need a recursive approach:

def flatten_deep(nested):
flat = []
for item in nested:
if isinstance(item, list):
flat.extend(flatten_deep(item))
else:
flat.append(item)
return flat

deeply_nested = [1, [2, [3, [4, 5]], 6], [7, 8]]

print(flatten_deep(deeply_nested))

Output:

[1, 2, 3, 4, 5, 6, 7, 8]
tip

For Python 3.3+, you can also use yield from with a generator for a more memory-efficient recursive approach:

def flatten_deep(nested):
for item in nested:
if isinstance(item, list):
yield from flatten_deep(item)
else:
yield item

deeply_nested = [1, [2, [3, [4, 5]], 6], [7, 8]]
print(list(flatten_deep(deeply_nested)))
# Output: [1, 2, 3, 4, 5, 6, 7, 8]

Comparison of Approaches​

MethodTime ComplexityMemory EfficientBest For
itertools.chain.from_iterable()O(n)āœ… (lazy iterator)Large datasets (recommended)
List comprehensionO(n)āŒ (builds full list)Clean, readable one-liners
for loop with extend()O(n)āŒ (builds full list)Beginners, custom logic needed
functools.reduce()O(n²)āŒFunctional programming style
sum(nested, [])O(n²)āŒQuick one-liner, small lists only
numpy.concatenate()O(n)āŒNumeric data with NumPy already in use
Recursive functionO(n)āœ… (with generator)Deeply or irregularly nested lists

Conclusion​

For most use cases, itertools.chain.from_iterable() is the best choice. It's fast, memory-efficient, and handles large datasets gracefully.

List comprehension is a great alternative when you prefer concise, readable code.

Avoid sum() and reduce() with list concatenation for large lists due to their quadratic performance. If your data is deeply nested, use a recursive function to handle arbitrary nesting depths.

Choose the approach that matches your data size, nesting depth, and readability preferences.