Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to loop a list of lists of varying depth?

I have a data structure like this (the actual lists of lists are very long and of varying depth). I do know their depth beforehand.

 a=( [1,2], [2,3,[4,5]] )
 b=( [[1,2],[2,3]] )

A want to loop through each single list. How to best do this?

I don't want to end up doing something like this:

for l in a:
    if instance(l, list):
        for ll in l:
            if instance(ll, list): 
                ...
like image 532
LarsVegas Avatar asked Nov 11 '13 13:11

LarsVegas


3 Answers

Since you don't defined the purpose, i'm coding a function that sum all elements:

def rec_sum(lst):
    if not lst:
        return 0
    el = lst.pop()
    if isinstance(el, list):
        return rec_sum(el) + rec_sum(lst)
    else:
        return el + rec_sum(lst)

Even if you know the depth beforehand, it's easier to solve using recursion.

Remember that Python limits 1000 stack frames stacked. So, if your list have more than 1000 items, you should get an Exception.

If you think you can have more than 1000 items, here it is a mixed solution, that uses recursion and for loops. It is limited into 1000 levels, instead of 1000 items:

def rec_for_sum(lst):
    if not lst:
        return 0
    count = 0
    for el in lst:
        if not isinstance(el, list):
            count += el
        else:
            count += rec_for_sum(el)
    return count
like image 117
Lucas Ribeiro Avatar answered Nov 08 '22 05:11

Lucas Ribeiro


You can check if an object is a list and just then go deeper:

Also see How to check if an object is a list or tuple (but not string)?

def myprint(list):
    for i in list:
        if isinstance(i, list):
            myprint(i)
        else:
            print i
like image 1
Florian Groetzner Avatar answered Nov 08 '22 07:11

Florian Groetzner


You can use a combination of recursion and a generator:

def flatten_list(list_in):
    if isinstance(list_in,list):
        for l in list_in:
                for y in flatten_list(l):
                        yield y
    else:
        yield list_in


my_compound_list = [[1,2,3],[4,5,6],[7,8,9,[10,11,12,[13,14,15]]]]

print [f for f in flatten_list(my_compound_list)]
like image 1
James Avatar answered Nov 08 '22 05:11

James