June 6, 2019 * Python Programming

# Python - Flatten nested lists, tuples, or sets

• A highly nested list, tuple, or set has elements and sub-elements that are lists, tuples or sets themselves.
• Simplify to create a list from a very nested object is achieved by recursive flattening.

## Fast recursive flatten function

Function flatten2list recursively visits elements within a nested structure and creates a flat final list or all the elements. This is the faster way to flatten a very complicated list, but the trade-off is more memory usage.

flatten2list: recursive flattening of a list, tuple or set

def flatten2list(object):
gather = []
for item in object:
if isinstance(item, (list, tuple, set)):
gather.extend(flatten2list(item))
else:
gather.append(item)
return gather

nested = [[1, [2, {3, 4}]], (5, 'abc', {6, ('d', 7)}, [8, 9]), 'e', 10]
flattened = flatten2list(nested)
print(flattened)

Code output:
[1, 2, 3, 4, 5, 'abc', 6, 'd', 7, 8, 9, 'e', 10]

## Flattening with iterators

Flattening of highly nested lists, tuples or sets can be achieved with less memory burden by modifying the function as an iterator. The final step casts the elements into a list. This is slightly slower than flatten2list.

flatten: simplify highly nested list into a flat structure

def flatten(object):
for item in object:
if isinstance(item, (list, tuple, set)):
yield from flatten(item)
else:
yield item

nested = [[1, [2, {3, 4}]], (5, 'abc', {6, ('d', 7)}, [8, 9]), 'e', 10]
flattened = list(flatten(nested))
print(flattened)

Code output:
[1, 2, 3, 4, 5, 'abc', 6, 'd', 7, 8, 9, 'e', 10]

In both the functions, each element is tested for being a list, tuple or set. If true, then the flatten function is called recursively till the final element is simply an item. This item is returned and added to the final linear list of values. If we had not done recursion, then the flatten function would stop at a certain depth.

## Partial flattening without recursion

Consider the following list comprehension, where lists within lists are flattened out. Simplification will be for single level, as there is no recursion.

Single level nested list simplification

from itertools import chain

#list of lists to flatten
nested_list = [[1, 2], [3, [4, 5]]]

#method 1: list comprehension
flatten1 = [element for items in nested_list for element in items]
print("Method 1 =", flatten1)

#method 2: itertools
flatten2 = list( chain( *nested_list))
print("Method 2 =", flatten2)

Code output:
Method 1 =[1, 2, 3, [4, 5]]
Method 2 =[1, 2, 3, [4, 5]]

The above example shows that [1, 2] is a sublist and is simplified. The element 3 from sublist [3, [4, 5]] is also a first order nested element and is also added to flattened list. However, the code cannot flatten the next level of nesting in [4, 5] by either list comprehension or itertools library. A more detailed treatment of flattening shows simpler cases.