a list might be like [[1,2,3],4,[5,6,7,8],[9]]
and i want to flatten it to [1,2,3,4,5,6,7,8,9]
. how easy is this to do if it is only 2 levels like that? what if it goes even deeper like [[1,2,3],4,[5,[[6,7],8]],[9]]
. is it any easier as a list than any type of iterator? would this be any easier if the iterators were ranges?
There is a generator function
here. Look at it.
looking for something simpler. i think i am getting close.
This could be simpler and should work:
>>> m = [[1,2,3],4,[5,[[6,7],8]],[9]]
>>> def flatten(lst):
... for item in lst:
... try:
... yield from flatten(item)
... except TypeError:
... yield item
...
>>> list(flatten(m))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
I should mention that if list contains string(s) function fails miserably (maximum recursion depth exceeded)
you could test for list type somewhere to avoid trying to iterate a string.
* Skaperen thinks that code would be a great example for the language reference
that code gave me hints, but i wanted something that would also work in Python2, so no
yield from. i came up with this code, which works without being a generator at all. i created it as a code file with test code, instead of an interactive session, since i wanted to keep it.
flatten.py:
def flatten(*a):
if len(a)==1:
l=[]
flatten(a[0],l)
return l
if isinstance(a[0],list):
for e in a[0]:
flatten(e,a[1])
return
a[1].append(a[0])
return
x=[[1,2,3],4,[5,[[6,7],8]],[9]]
print(repr(x))
y=flatten(x)
print(repr(y))
(Aug-06-2018, 06:03 AM)perfringo Wrote: [ -> ]I should mention that if list contains string(s) function fails miserably (maximum recursion depth exceeded)
I had this issue with strings. You can see the link in my prev. post.
I like the way you use try/except. I didn't even think to catch an exception.
Let's bend our minds little further
This should be compatible with Python 2 and handle strings as well:
def flatten(lst):
def _flatten(lst, result):
if type(lst) is not list:
result.append(lst)
else:
for item in lst:
result = result + flatten(item)
return result
return _flatten(lst, [])
This will produce:
>>> n = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ['x','y','z']], 6]
>>> flatten(n)
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]
def flatten(lst):
result = []
for item in lst:
if isinstance(item, (list, tuple)): # You may add more container types if needed
result.extend(flatten(item))
else:
result.append(item)
return result
n = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ('x','y','z')], 6]
print flatten(n)
Output:
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]
(Aug-06-2018, 10:18 AM)buran Wrote: [ -> ]def flatten(lst):
result = []
for item in lst:
if isinstance(item, (list, tuple)): # You may add more container types if needed
result.extend(flatten(item))
else:
result.append(item)
return result
This is the reason I like Python - smart people (like buran) can achieve desired results with minimal and very readable piece of code. I have lot of work to do in smart part

Using a generic function to dispatch according to the argument's type
>>> import functools
>>> @functools.singledispatch
... def flatten(x):
... return [x]
...
>>> @flatten.register(list)
... @flatten.register(tuple)
... def _(x):
... return [z for y in x for z in flatten(y)]
...
>>> a = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ('x','y','z')], 6]
>>> flatten(a)
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]