Flatten a nested list in Python
Flatten one level with a comprehension or itertools.chain, and use a list-specific recursive function when the nesting depth varies.
For a list of lists, use a nested comprehension: [item for group in groups for item in group]. It removes one level of nesting. A recursively nested structure needs a different policy about which objects should be expanded.
Flatten one level
groups = [[1, 2], [3, 4], [5, 6]]
flat = [item for group in groups for item in group]
print(flat) # [1, 2, 3, 4, 5, 6]
The loop order matches the equivalent statements:
flat = []
for group in groups:
for item in group:
flat.append(item)
Use an iterator when you do not need a list
from itertools import chain
items = chain.from_iterable(groups)
for item in items:
print(item)
chain.from_iterable() yields values as you consume them. Calling list(chain.from_iterable(groups)) materializes the entire result, so that form does not eliminate the output list's memory cost. The input groups must themselves be iterable.
Expand nested lists recursively
def flatten(values):
result = []
for item in values:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
print(flatten([1, [2, [3, [4]]]])) # [1, 2, 3, 4]
This function expands lists only. Strings, bytes, tuples, and other objects remain individual values. Deep nesting can reach Python's recursion limit, and self-referential lists need cycle detection. An iterative traversal is another option when those constraints matter.
Avoid repeated list concatenation
sum(groups, []) works for lists of lists, but repeatedly copies the accumulated prefix. Its cost can grow quadratically as the number of small groups increases. A comprehension or iterator makes the intended traversal clearer.
FAQ
What happens to strings? chain.from_iterable(["ab", "cd"]) yields individual characters. The recursive list-only function above keeps strings intact. If you generalize it to all iterables, explicitly exclude strings and bytes when they should remain atomic.
What about NumPy? array.flatten() returns a copy. array.ravel() returns a view when possible and a copy when needed; layout and order affect the result. Do not assume one is always faster for your data.
Is there a library for deeper structures? more_itertools.collapse offers configurable flattening. Check its supported container and scalar behavior rather than assuming it is identical to a list-only recursion.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan