Oliver
Oliver

Reputation: 323

How to find the number of nested lists in a list?

The function takes a list and returns an int depending on how many lists are in the list not including the list itself. (For the sake of simplicity we can assume everything is either an integer or a list.)

For example:

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]

count_list(x) # would return 8

I think using recursion would help but I am not sure how to implement it, this is what I have so far.

def count_list(a,count=None, i=None):

    if count==None and i==None:
        count=0
        i=0
    if i>len(a)
        return(count)
    if a[i]==list
       i+=1
       count+=1
       return(count_list(a[i][i],count))
    else:
        i+=1
        return(count_list(a[i]))

Upvotes: 20

Views: 10000

Answers (6)

Kasravnd
Kasravnd

Reputation: 107357

You can use a recursive function as following:

In [14]: def count_lists(l):
    ...:     return sum(1 + count_lists(i) for i in l if isinstance(i,list))
    ...: 

In [15]: 

In [15]: x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]

In [16]: count_lists(x)
Out[16]: 8

Upvotes: 25

LightVading
LightVading

Reputation: 36

lst = [1,2,[[[]]],[[]],3,4,[1,2,3,4,["[[[[[][[[[[[[[[[[[["] ] ]

strlst = re.sub("'.*?'", '',str(lst))
print(strlst.count("[")-1)

Making the list a string will allow you to use count function on the number of [ or ] giving you an answer

But if a string within the list contains either [ or ] they will be included so removing all strings within the list using regex eliminates this problem

Upvotes: 0

lvella
lvella

Reputation: 13491

This seems to do the job:

def count_list(l):
    count = 0
    for e in l:
        if isinstance(e, list):
            count = count + 1 + count_list(e)
    return count

Upvotes: 18

benji
benji

Reputation: 606

I like this tail recursive solution, although it's not much use in Python...

def count_lists(l, counter):
    if (len(l) == 0):
        return counter
    else:
        e = l.pop(0)
        if (isinstance(e, list)):
            l.extend(e)
            return count_lists(l, 1 + counter)
        else:
            return count_lists(l, counter)

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]]]]
print(count_lists(x, 0))

Upvotes: 3

Hai Vu
Hai Vu

Reputation: 40793

Here is a non-recursive solution:

  1. First, put every items of the list into a stack
  2. Keep popping an item off the stack until it is exhausted
  3. If the item is a list: a) count it, b) push every items in in to the stack

The code:

def count_list(lst):
    """ Given a master list, count the number of sub-lists """
    stack = lst[:]
    count = 0
    while stack:
        item = stack.pop()
        if isinstance(item, list):
            # If the item is a list, count it, and push back into the
            # stack so we can process it later
            count += 1
            stack.extend(item)
    return count

Upvotes: 5

ojy
ojy

Reputation: 2482

A functional-style solution without loops. Recursively processes the first element of a list, and the tail of a list. Add one for each empty-list encountered (that is, once we finish processing some list, its tail becomes empty, and we add 1 to the result). And subtract 1 for the list itself.

def number_of_lists(x):
    f = lambda x: 0 if not isinstance(x,list) else (f(x[0]) + f(x[1:]) if len(x) else 1)
    return f(x) - 1

Results:

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]
number_of_lists(x)
>> 8

Upvotes: 3

Related Questions