Kodeclik Blog
Flattening a nested list in Python
Assume you are given a Python list with two levels of nesting, like so:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
['The Strip','Las Vegas','Nevada']]
print(tourist_locations)
Note that each element of the list is another list. The first and second lists contain two elements each while the third list contains three elements.
The output is:
[['Miami', 'Florida'], ['Austin', 'Texas'],
['The Strip', 'Las Vegas', 'Nevada']]
We wish to flatten the list into:
['Miami', 'Florida', 'Austin', 'Texas',
'The Strip', 'Las Vegas', 'Nevada']
Let us learn how to do it!
Method 1: Flatten a nested list using list comprehension
The first way to flatten the list is to use a list comprehension, like so:
flattened = [x for l in tourist_locations for x in l]
print(flattened)
Note that the list comprehension is akin to two for loops. The first for loop is “for l in tourist_locations”, i.e., it iterates through every element (which is referred to as “l”). Then we iterate within “l” with the second for loop (with the “for x in l” part). The x’s are the final nested elements. These x’s are returned to form the list called “flattened”.
The output is:
['Miami', 'Florida', 'Austin', 'Texas',
'The Strip', 'Las Vegas', 'Nevada']
as we expected.
Note that this approach works only if every element of the original list is a list and that list does not contain any further lists. For instance, the following example will not work:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
'Washington, D.C',['The Strip','Las Vegas','Nevada']]
In this list above, we have a single location (“Washington, D.C.”) which is not a list. In fact if we run the above program on it, we will get:
['Miami', 'Florida', 'Austin', 'Texas', 'W', 'a', 's', 'h', 'i', 'n',
'g', 't', 'o', 'n', ',', ' ', 'D', '.', 'C', 'The Strip',
'Las Vegas', 'Nevada']
which is clearly not what we intended! This is because in trying to unpack the third element (which is a string and not a list) the iterator cycles through every character in the string.
A second situation where this approach will not work is if we have more levels of nesting.
If our input is:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
[['Washington, D.C']],['The Strip','Las Vegas','Nevada']]
The output will be:
['Miami', 'Florida', 'Austin', 'Texas', ['Washington, D.C'],
'The Strip', 'Las Vegas', 'Nevada']
which is again not what we would have liked. This approach is able to strip away only one level of list nesting.
Nevertheless, this is a good method that works on examples where all elements are at the same level of nesting. Note that it does not expect that the individual lists have the same number of elements.
Method 2: Flatten a nested list using the Python sum() fuction
The Python sum() function is used often to return accumulated sums or in our case accumulated lists.
This approach is also short and sweet:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
['The Strip','Las Vegas','Nevada']]
print(sum(tourist_locations,[]))
The output will be:
['Miami', 'Florida', 'Austin', 'Texas',
'The Strip', 'Las Vegas', 'Nevada']
as in the first method. The sum() function takes an iterable as the first argument (in our case, it is the list we wish to flatten) and cycles through every element unpacking it. The results are accumulated with the second argument specifying the starting state (in this case, it is just the empty list).
If we give a non-empty starting state, like so:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
['The Strip','Las Vegas','Nevada']]
print(sum(tourist_locations,['Paris']))
The output will be:
['Paris', 'Miami', 'Florida', 'Austin', 'Texas',
'The Strip', 'Las Vegas', 'Nevada']
Note that ‘Paris’ is added to the flattened list (at the beginning, since it is the start state).
This second approach has all the shortcomings of the first approach and in addition will complain if we give a string as an element of the original list:
tourist_locations = [['Miami', 'Florida'],['Austin','Texas'],
'Washington, D.C.',['The Strip','Las Vegas','Nevada']]
print(sum(tourist_locations,['Paris']))
Python will complain with:
Traceback (most recent call last):
File "main.py", line 2, in <module>
print(sum(tourist_locations,['Paris']))
TypeError: can only concatenate list (not "str") to list
Method 3: Flatten an arbitrarily nested Python list using recursion
This final approach we will see is a foolproof one and works on multiple and arbitrary levels of nesting.
We iterate through the given list picking apart each element one by one. As we study each element we see if it is a list itself and if so recurse with its elements. If not we return. The elements as they are extracted are accumulated in a global variable (so this part is similar to how the sum() function above does it).
def flatten(l):
# if l is an empty list just return it
if (l == []):
return (l)
# if l is not a list but a string just return it
elif (type(l) is not list):
answer.append(l)
else:
# now l is a list
# we need to flatten everything and return that
for x in l:
flatten(x)
tourist_locations = [
'California', [[['Miami', 'Florida']]], 'Niagara Falls',
['Austin', 'Texas'], ['The Bellagio', ['Las Vegas', 'Nevada']]
]
print(tourist_locations)
answer = []
flatten(tourist_locations)
print(answer)
Note that in our tourist_locations list, we have strings, lists, as well as lists of lists. Note the arbitrariness of the nesting levels. The program will work like a charm:
['California', [[['Miami', 'Florida']]], 'Niagara Falls',
['Austin', 'Texas'], ['The Bellagio', ['Las Vegas', 'Nevada']]]
['California', 'Miami', 'Florida', 'Niagara Falls',
'Austin', 'Texas', 'The Bellagio', 'Las Vegas', 'Nevada']
Thus we have learnt three different ways to flatten a nested list. The first two approaches, involving list comprehensions and the sum() function work for a fixed, uniform, single level of nesting. The third approach works for arbitrary, multiple, levels of nesting.
If you liked this blogpost, learn more about the Python reduce() function.
For more Python content, checkout the math.ceil() and math.floor() functions! Also
learn about the math domain error in Python and how to fix it!
Interested in more things Python? Checkout our post on Python queues. Also see our blogpost on Python's enumerate() capability. Also if you like Python+math content, see our blogpost on Magic Squares. Finally, master the Python print function!
Want to learn Python with us? Sign up for 1:1 or small group classes.