Reputation: 55
I have some data in a messy nested list with many different (sub)-levels. I do not really care about these levels and just want the data in one big list of lists.
I've already looked for how to flatten a list of list or a nested list (for instance here, here and here), but solutions to those problems are not applicable here (I think).
So basically what I need is:
nested_list = [[[1, 2, 3], [[5, 6, 7], [8, 9, 10, 11, 23]]], [4], [[12, 13, 14], [[15, 16], [[17, 18], [19, 20]]]], [21, 22, 25, 26]]
unnested_list = nested_to_listoflist( nested_list )
#=> [ [1, 2, 3], [5, 6, 7], [8, 9, 10, 11, 23], [4], [12, 13, 14], [15, 16], [17, 18], [19, 20], [21, 22, 25, 26] ]
Any suggestions?
Upvotes: 2
Views: 383
Reputation: 44148
Generator function flatten is passed a list and looks at each sublist. If the length of the sublist is 0 or if the first element of the sublist is not another list, it just yields the sublist as the next list to be added to the result. Otherwise it recursively processes the sublist. Function nested_to_listoflist just assembles all of the "yielded" lists into one final list.
def flatten(l):
for el in l:
if not el or not isinstance(el[0], list):
yield el
else:
yield from flatten(el)
def nested_to_listoflist(l):
return [el for el in flatten(l)]
# or return list(flatten(l))
nested_list = [[[1, 2, 3], [[5, 6, 7], [8, 9, 10, 11, 23]]], [4], [[12, 13, 14], [[15, 16], [[17, 18], [19, 20]]]], [21, 22, 25, 26]]
unnested_list = nested_to_listoflist(nested_list)
print(unnested_list)
Prints:
[[1, 2, 3], [5, 6, 7], [8, 9, 10, 11, 23], [4], [12, 13, 14], [15, 16], [17, 18], [19, 20], [21, 22, 25, 26]]
Upvotes: 2
Reputation: 1280
You can use this recursive algorithm:
def flatten(l):
result = []
for item in l:
if isinstance(item,list):
if len(item)>0 and isinstance(item[0], list):
result.extend(flatten(item)) # recursion
else:
result.append(item)
else:
result.append([item]) # decide what to do with stand_alone integers
return result
nested_list = [[[1, 2, 3], [[5, 6, 7], [8, 9, 10, 11, 23]]], [], [[12, 13, 14], [[15, 16], [[17, 18], [19, 20]]]], [21, 22, 25, 26],3]
flattened_list = flatten(nested_list)
# [[1, 2, 3], [5, 6, 7], [8, 9, 10, 11, 23], [], [12, 13, 14], [15, 16], [17, 18], [19, 20], [21, 22, 25, 26], [3]]
Upvotes: 0
Reputation: 914
Try this:
def nested_to_listoflist(nested_list):
if len(nested_list) == 0 or not isinstance(nested_list[0], list):
return [nested_list]
unnested_list = []
for l in nested_list:
unnested_list += nested_to_listoflist(l)
return unnested_list
Upvotes: 1
Reputation: 887
A funny way of doing it (not recommendable):
l = str(nested_l)
inner = False
new_l = "["
for i in range(2,len(l)):
if l[i] == "]" and inner:
inner = False
elif l[i] == "[" and not inner:
inner = True
elif l[i] == "[" and inner or l[i] == "]" and not inner:
continue
new_l+=l[i]
new_l += "]"
new_l = eval(new_l)
Upvotes: 1
Reputation: 599
I think this will do the job for you,
open_ = []
open_.append(nested_list)
res = []
while len(open_) > 0:
element = open_.pop()
for item in element:
if isinstance(item, list):
open_.append(item)
else:
res.append(element)
break
Upvotes: 1