16

I have a list assigned to the variable my_list. The value of my_list is [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]. I need to find the length of my_list, but len(my_list) only returns 3. I want it to return 11. Is there any Python functions that will return the full length of my_list nested lists and all.

Example:

Input
[[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

Output
11

I would like if this worked for not only numbers, but strings also.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
michaelpri
  • 3,521
  • 4
  • 30
  • 46
  • It should be a rule. How much 'nested' are we talkin about? –  Jan 04 '15 at 01:33
  • So this is your list only? Can't be change with another nested lists? –  Jan 04 '15 at 01:34
  • 1
    Do you want this to work with nested lists that may contain strings, or do the lists only contain numbers? – PM 2Ring Jan 04 '15 at 01:40
  • Can you list the 11 lists found in your input? – thefourtheye Jan 04 '15 at 01:44
  • 3
    @michaelpri Then your question is a bit misleading, "find the length of all the nested lists?" – thefourtheye Jan 04 '15 at 01:46
  • 2
    Here's a nice function to flatten arbitrary nested lists: http://stackoverflow.com/a/2158532/4014959 . Use that to flatten your nested list, then you just need to get the `len()` of the flattened list. – PM 2Ring Jan 04 '15 at 01:50
  • possible duplicate of [Flatten (an irregular) list of lists in Python](http://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python) –  Jan 04 '15 at 01:51
  • @michaelpri please see my updated answer. Let me know if that's what you needed. – Jobs Jan 04 '15 at 01:54
  • @PM2Ring I'm getting `TypeError: object of type 'generator' has no len()` when I do print(len(flatten(deep_nested_list))) – ruslaniv Sep 05 '20 at 13:50
  • 1
    @RusI In general, you don't know how many items a generator will produce until you run it, and some generators never stop producing items. If you have a generator that you know has a finite size, you can produce a list from it & then call `len()` on that list. Eg, `len(list(flatten(deep_nested_list)))` – PM 2Ring Sep 05 '20 at 23:50

7 Answers7

19

This function counts the length of a list, counting any object other than list as length 1, and recursing on list items to find the flattened length, and will work with any degree of nesting up to the interpreters maximum stack depth.

def recursive_len(item):
    if type(item) == list:
        return sum(recursive_len(subitem) for subitem in item)
    else:
        return 1

Note: depending on how this will be used, it may be better to check if the item is iterable rather than checking if it has the type list, in order to correctly judge the size of tuples, etc. However, checking if the object is iterable will have the side effect of counting each character in a string rather than giving the string length 1, which may be undesirable.

stonesam92
  • 4,307
  • 2
  • 19
  • 24
6

As an alternative, you can use flatten with len:

from compiler.ast import flatten

my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

len(flatten(my_list))
11

PS. thanks for @thefourtheye pointing out, please note:

Deprecated since version 2.6: The compiler package has been removed in Python 3.

Alternatives can be found here: Python 3 replacement for deprecated compiler.ast flatten function

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Anzel
  • 19,825
  • 5
  • 51
  • 52
6

hack solution, someone had to post it. Convert list to string (leave the heavy lifting / recursion to __str__ operator) then count the commas, add 1.

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
>>> str(my_list).count(",")+1
11

(works for integers & floats, of course fails with strings because they can contain commas)

EDIT: this hack doesn't account for empty lists: we have to remove [] elements:

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4],[]]]]  # added empty list at the end
>>> s = str(my_list)
>>> s.count(",")-s.count("[]")+1   # still 11
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
2

This is an alternative solution, which might be not so performant, since it fills a new flattened list, which is returned at the end:

def flatten_list(ls, flattened_list=[]):
    for elem in ls:
        if not isinstance(elem, list): 
            flattened_list.append(elem)
        else:
            flatten_list(elem, flattened_list)
    return flattened_list

flatten_list intuitively flattens the list, and then you can calculate the length of the new returned flattened list with the len() function:

len(flatten_list(my_list))
nbro
  • 15,395
  • 32
  • 113
  • 196
2

You are essentially looking for a way to compute the number of leaves in a tree.

 def is_leaf(tree):
        return type(tree) != list

def count_leaves(tree):
    if is_leaf(tree):
        return 1
    else:
        branch_counts = [count_leaves(b) for b in tree]
        return sum(branch_counts)

The count_leaves function counts the leaves in a tree by recursively computing the branch_counts of the branches, then summing those results. The base case is when the tree is a leaf, which is a tree with 1 leaf. The number of leaves differs from the length of the tree, which is its number of branches.

Jobs
  • 3,317
  • 6
  • 26
  • 52
0

Here is my implementation:

def nestedList(check):
    returnValue = 0
    for i in xrange(0, len(check)):
        if(isinstance(check[i], list)):
            returnValue += nestedList(check[i])
        else:
            returnValue += 1
    return returnValue
ProgrammingIsAwsome
  • 1,109
  • 7
  • 15
0

This is my best attempt, utilizing recursion, and only uses the standard library and a visual. I try to not use custom libraries

def listlength(mylist, k=0, indent=''):
    for l1 in mylist:
        if isinstance(l1, list):
            k = listlength(l1, k, indent+'  ')
        else:
            print(indent+str(l1))
            k+=1
    return k

a = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
listlength(a)
# 11

and for good measure

a = []
x = listlength(a)
print('length={}'.format(x))
# length=0



a = [1,2,3]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#length=3


a = [[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#length=3


a = [[1,2,3],[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#  1
#  2
#  3
#length=6

a = [1,2,3, [1,2,3],[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#  1
#  2
#  3
#  1
#  2
#  3
#length=9


a = [1,2,3, [1,2,3,[1,2,3]]]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#  1
#  2
#  3
#    1
#    2
#    3
#length=9


a = [ [1,2,3], [1,[1,2],3] ]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#  1
#    1
#    2
#  3
#length=7
nagordon
  • 1,307
  • 2
  • 13
  • 16