5

This is what I've tried:

def recursive_list_counter(l):
    sum = 0
    for e in l:
        if type(e) == type([]):
            #print e
            sum += 1
            recursive_list_counter(e)
    return sum 

# should be 6 if I count the first also
recursive_list_counter([[[13, 7], 90], 2, [1, 100, [5, [2]]], 8, 6])

I want to use recursion to retrieve the number of lists within a list, counting the original list also.

6 Answers 6

10

Your recursive call ignores what is returned. Add the return value:

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

Note that the outer list is ignored in the count, so the call returns 5, not 6.

Furthermore, you should use isinstance() to test if an object is of a given type.

If you want to see 6, count the current list in the function, and leave counting nested lists to the recursive call:

def recursive_list_counter(l):
    sum = 1
    for e in l:
        if isinstance(e, list):
            sum += recursive_list_counter(e)
    return sum 
Sign up to request clarification or add additional context in comments.

2 Comments

I would change type(e) == type([]) this part
To count the outer list, just start with sum = 1 and lose sum += 1.
9

For your given example, if all you have are numbers within lists, you can try converting to string and counting the number of [

>>> li = [[[13, 7], 90], 2, [1, 100, [5, [2]]], 8, 6]
>>> str(li).count('[') 
6

5 Comments

But of course your solution fails miserably as soon as there is s string inside the list containing an opening bracket. And it is way to costly because generating the string representation is not necessary for this task.
@Alfe I know, but still, its awesome!
@Alfe Agree with the part this fails if there are strings with the bracket in one of the lists. My answer begins with the assumption that is not the case. Disagree with converting to string being costly, recursion implies call stack, and I won't be too sure on which is faster, without proper tests.
This is a nice trick and all, but the OP was asking about recursion. :-)
Nice trick, agreed, but has drawbacks which I wouldn't want to support, hence my critique. Consider an element whose str function takes lots of time.
3

A true functional solution would be this:

def recursive_list_counter(li):
  return 1 + sum(map(recursive_list_counter, li)) if isinstance(li, list) else 0

To count all elements in the list use this slightly altered version:

def recursive_element_counter(li):
  return sum(map(recursive_element_counter, li)) if isinstance(li, list) else 1

2 Comments

Maybe you are trying an outdated version of my answer?
Actually I copied element counter by mistake, sorry.
3

I think this should do the trick. But I guess I was too slow, I already see 3 other answers. :P

#!/usr/bin/env python

def lcount(l):
    count = 0 
    if isinstance(l, list):
        count+=1
        count+=sum([lcount(x) for x in l]) 

    return count


list_ = [ [ [1, 2, 3], [1, 4, 5], [7, 8, 9]], [ 1, 2, 7], 1, 3, ]
print lcount(list_)

1 Comment

@user2144553 I'm not sure how you're running this or what input you're using but, runs for me, see ideone.com/2InIOy for live example
3

Three important points:

  • use isinstance to check the type
  • don't use sum as a variable since it's already a built-in function
  • recursive fonctions should start with the stopping condition (here: not isinstance(l, list))

Here is your function :

def recursive_list_counter(l):
    if not isinstance(l, list):
        return 0
    return 1 + sum(recursive_list_counter(e) for e in l)

Comments

2

Actually, the problem is very simple. Everytime you called recursive_list_counter, you create a new local variable sum, instead of incrementing the global one.

sum = 0
def recursive_list_counter(l):
    global sum
    for e in l:
        if type(e) is list: #this is the same, but a better practice.
            #print e
            sum += 1
            recursive_list_counter(e)
    return sum 

recursive_list_counter([[[13, 7], 90], 2, [1, 100, [5, [2]]], 8, 6]) #returns 5

You can also increment sum recursively:

if type(e) is list:
    sum += 1
    sum += recursive_list_counter(e)

Hope this helps!

3 Comments

If you are going to test for the specific type, use is: type(e) is list; but it is much better to use isinstance() because then you allow for subclasses of list as well.
Hi, your comment #returns 6 is a bit misleading! Your code actually returns 5, but that's normal since we start in a list.
@MartijnPieters Thanks, i forgot that for a second.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.