Reputation: 53
I have a nested list of lists occurring in the form of
A = [[a,b],[c,d]] or [[[a,b],[c,d]]] or [[[[a,b],[c,d]]]] or [[[[[a,b],[c,d]]]]]
and so on. These forms of A
don't occur at the same time.
How can I code to peel the list, no matter how nested A may be, and obtain only:
[a,b]
[c,d]
I tried this:
def Peel_list(Features):
try:
for lon,lat in Features:
print((lon,lat))
except:
for Feature in Features:
for t_list in Feature:
for A in t_list:
for lon,lat in A:
print((lon,lat))
return()
But it only works for limited A.
Upvotes: 4
Views: 609
Reputation: 71451
You can use recursion with a generator:
def flatten(d):
if all(not isinstance(i, list) for i in d):
yield d
else:
for i in d:
yield from flatten(i)
print(list(flatten([[[[['a', 'b'], ['c', 'd']]]]])))
Output:
[['a', 'b'], ['c', 'd']]
Upvotes: 0
Reputation: 2818
Here is another recursion based solution:
l1 = [[[['a','b'],['c','d'], [[1,2]]]]]
l2 = [[[[['a','b'],['c','d']]]]]
def f(inp):
# you can skip this if statement if you are sure that there is no empty nested list
if not inp:
return [[]]
if (all(isinstance(element, list) for element in inp)):
return [elem for x in inp for elem in f(x)]
else:
return [inp]
With all()
, a condition can be checked on every element of an iterable.
Results would be:
f(l1) #[['a', 'b'], ['c', 'd'], [1, 2]]
f(l2) #[['a', 'b'], ['c', 'd'], []]
Upvotes: 0
Reputation: 273
A simple approach for the cases that you've provided would be to have a while-loop that continually checks if the size of the list is 1 and modifies your list to contain only the single element (this would get rid of the outermost list).
x = [[[[[a,b],[c,d]]]]]
while len(x) == 1:
x = x[0]
// result is x = [[1, 2], [3, 4]]
The general approach for when you have elements nested in an arbitrary number of lists would be Mitchel's answer.
Upvotes: 3
Reputation: 415
you can also try numpy ravel function on your list, output will be a 1D array.
Upvotes: 0
Reputation: 3418
Generally when we want to deal with a problem of arbitrarily nested objects recursion is a good place to start. Here we want to keep "digging down" until we hit the base case, in our case any non list value. The code looks something like this
test = [1, [3,4],[[5]], [[[6]]]]
peeled = []
def peel(myList, peeled):
for val in myList:
if isinstance(val, list):
if not isinstance(val[0], list):
peeled.append(val)
else:
peel(val, peeled)
else:
peeled.append(val)
peel(test, peeled)
print(peeled)
This will give you something like
[1, [3, 4], [5], [6]]
Upvotes: 4