A list comprehension with two fors, read left to right like the nested loops it replaces.
weeks = [[3, 5, 2], [8, 1], [4, 4, 6, 0]] days = [n for week in weeks for n in week] print(days)
[3, 5, 2, 8, 1, 4, 4, 6, 0]
If the order of the fors looks backwards, write out the loop it stands for; the comprehension keeps exactly that order:
weeks = [[3, 5, 2], [8, 1]] days = [] for week in weeks: for n in week: days.append(n) print(days)
[3, 5, 2, 8, 1]
Without building the list: chain
itertools.chain.from_iterable walks through the inner lists one after another without creating a new list. Good when you're going to loop over the result once, or sum it:
from itertools import chain weeks = [[3, 5, 2], [8, 1], [4, 4, 6, 0]] print(sum(chain.from_iterable(weeks))) print(list(chain.from_iterable(weeks)))
33 [3, 5, 2, 8, 1, 4, 4, 6, 0]
Skip sum(nested, [])
It looks clever and gives the right answer:
print(sum([[1, 2], [3], [4, 5]], []))
[1, 2, 3, 4, 5]
But each + copies everything collected so far into a new list. With 10 inner lists that's nothing; with 10,000 it copies millions of items. The comprehension and chain touch each item once.
Deeper nesting
The methods above flatten one level. For lists nested to any depth, recurse:
def flatten(items): for item in items: if isinstance(item, list): yield from flatten(item) else: yield item print(list(flatten([1, [2, [3, [4]], 5], [[6]]])))
[1, 2, 3, 4, 5, 6]
Check for list specifically, not "anything you can loop over": a string is iterable too, and each character is a one-character string, so a general check would never stop.
Working with numbers in a grid? NumPy's array.ravel() flattens a whole matrix in one call.