Finding length of the longest list in an irregular list of lists

Question:

I have to find the longest list inside a list of lists.

For example:

longest([1,2,3]) returns 3

longest([[[1,2,3]]]) also returns 3 (inner list is 3)

longest([[], [3,[4,5],[2,3,4,5,3,3], [7], 5, [1,2,3], [3,4]], [1,2,3,4,5]]) returns 7 (list [3,[4,5],[2,3,4,5,3,3], [7], 5, [1,2,3], [3,4]] contains 7 elements)

Right now I have this code, but it doesn’t do the trick with the first two examples.

def longest(list1):
    longest_list = max(len(elem) for elem in list1)
    return longest_list

Maybe recursion will help?

Asked By: Liis Krevald

||

Answers:

Python 3.3 version:

def lengths(x):
    if isinstance(x,list):
        yield len(x)
        for y in x:
            yield from lengths(y)

usage:

>>> l = [[], [3,[4,5],[2,3,4,5,3,3], [7], 5, [1,2,3], [3,4]], [1,2,3,4,5]]
>>> max(lengths(l))
7

In python 2.6+ you don’t have the yield from statement (was introduced in python 3.3), so you have to change the code slightly:

def lengths(x):
    if isinstance(x,list):
        yield len(x)
        for y in x:
            for z in lengths(y):
                yield z
Answered By: fferri

Indeed, recursion can solve this.

def longest(lst):
    if type(lst) is not list:
        return 0
    max = len(lst)
    for i in lst:
        max_i = longest(i)
        if max_i > max:
            max = max_i
    return max
Answered By: wvdz

You can do this with recursion:

def longest(list1) :
    l = 0
    if type(list1) is list :
        l = len(list1)
        if l > 0 :
            l = max(l,max(longest(elem) for elem in list1))
    return l

(online demo).

The code first checks if this is list we are dealing with. If so, we first take the len of the list. Next we perform a recursive call on its elements. And calculate the maximum longest of the elements. If the maximum is greater than the length itself. We return that maximum, otherwise we return the length.

Because the longest of a non-list is zero, the recursion will stop, and we have an answer for single elements to be used in the inductive step.

Answered By: Willem Van Onsem

Here is a recursive solution for any depth list:

def longest(l):
    if not isinstance(l, list):
        return 0
    return max(
            [len(l)] 
            + [len(subl) for subl in l if isinstance(subl, list)] 
            + [longest(subl) for subl in l]
            )
Answered By: cr1msonB1ade

Another recursive function using map:

def longest(a):
    return max(len(a), *map(longest, a)) if isinstance(a, list) and a else 0

In [2]:  longest([1,2,3])
Out[2]:  3

In [3]:  longest([[[1,2,3]]]) 
Out[3]:  3

In [4]:  longest([[], [3,[4,5],[2,3,4,5,3,3], [7], 5, [1,2,3], [3,4]], [1,2,3,4,5]])
Out[4]:  7

and iteratively:

def longest(a):
    mx = 0
    stack = [a[:]]
    while stack:
        cur = stack.pop()
        if isinstance(cur, list):
            mx = max(mx, len(cur))
            stack += cur
    return mx

In [6]:  longest([1,2,3])
Out[6]:  3

In [7]:  longest([[[1,2,3]]]) 
Out[7]:  3

In [8]:  longest([[], [3,[4,5],[2,3,4,5,3,3], [7], 5, [1,2,3], [3,4]], [1,2,3,4,5]])
Out[8]:  7
Answered By: dting

These simple few lines works for me, my list is a nested one (list of lists)

#define the function#
def find_max_list(list):
    list_len = [len(i) for i in list]
    print(max(list_len))

#print output#
find_max_list(your_list)
Answered By: FeiLiao

Using the toolz library, this can be achieved like this:

from toolz.curried import count

def longest(your_list): 
    return max(map(count, your_list))

One caveat: This doesn’t work if your_list contains non-iterables.

Answered By: Mathias Wedeken

You can make use of enumerate, sorted and behavior of list:

ll = [[10,20], [1,2,3,4,5], [7,8,9]]
longest = ll[sorted([(i,len(l)) for i,l in enumerate(ll)], key=lambda t: t[1])[-1][0]]

>>longest
>>[1,2,3,4,5]

Explanation

  1. Create list of tuple with index as first element and len(l) (length of list) as second element:

    [(i,len(l)) for i,l in enumerate(ll)]

    >>[(0, 2), (1, 5), (2, 3)]

  2. Sort above list by second element in tuple that tuple with longest length gets to the end of the list:

    sorted([(i,len(l)) for i,l in enumerate(ll)], key=lambda t: t[1])

    >>[(0, 2), (2, 3), (1, 5)]

  3. Catch the last tuple and its first element:

    sorted([(i,len(l)) for i,l in enumerate(ll)], key=lambda t: t[1])[-1][0]

    >>1

  4. Use above result as the index in ll to get the longest list:

    ll[sorted([(i,len(l)) for i,l in enumerate(ll)], key=lambda t: t[1])[-1][0]]

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

Answered By: binaryEcon

The following will give you the indices of longest link:

import numpy as np
def find_max_list_idx(list):
    list_len = [len(i) for i in list]
    return np.argmax(np.array(list_len))

Example

a=[[1],[1,2,3],[3,4]]
print(find_max_list_idx(a))

'''
it will print index 1 as output
'''
Answered By: william007

Needs only one line:

max([len(i) for i in lst)])

When lst is a list of lists.

Answered By: Amir P
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.