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?
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
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
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
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.
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]
)
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
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)
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.
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
-
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)]
-
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)]
-
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
-
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]
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
'''
Needs only one line:
max([len(i) for i in lst)])
When lst
is a list of lists.
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?
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
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
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
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.
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]
)
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
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)
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.
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
-
Create
list
oftuple
with index as first element andlen(l)
(length of list) as second element:[(i,len(l)) for i,l in enumerate(ll)]
>>[(0, 2), (1, 5), (2, 3)]
-
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)]
-
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
-
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]
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
'''
Needs only one line:
max([len(i) for i in lst)])
When lst
is a list of lists.