If I want to add something to the great previous answers, here is my recursive flatten function which can flatten not only nested lists, but also any given container or any generally any object which can throw out items. This isdoes also work for any depth of nesting and it is a lazy iterator which yields the items as requested:
def flatten(iterable):
# These types won't considered a sequence or generally a container
exclude = str, bytes
for i in iterable:
try:
if isinstance(i, exclude):
raise TypeError
iter(i)
except TypeError:
yield i
else:
yield from flatten(i)
This way, you can exclude types you don't want them to be flattedflattened, like str or what else.
The idea is if an object can pass the iter() it's ready to yield items. So the iterable can have even generator expressions as an item.
Someone could argue that why: Why did you write this that generic when the OP didn't ask for it? okOK, you're right. I just felt like this might help someone (like it did for myself).
Test cases:
lst1 = [1, {3}, (1, 6), [[3, 8]], [[[5]]], 9, ((((2,),),),)]
lst2 = ['3', B'A', [[[(i ** 2 for i in range(3))]]], range(3)]
print(list(flatten(lst1)))
print(list(flatten(lst2)))
outputOutput:
[1, 3, 1, 6, 3, 8, 5, 9, 2]
['3', b'A', 0, 1, 4, 0, 1, 2]