I wrote this and its working fine with everything but when I have an empty list
in a given list(given_list=[[],1,2,3]
) it saying index is out of range. Any help?
I assume that the max element of an empty list is negative infinity.
This assumption will deal with the cases like [], [1,2,[],5,4,[]]
def find_max(L):
if len(L) == 0:
return float("-inf")
elif len(L) == 1:
if isinstance(L[0], list):
return find_max(L[0])
else:
return L[0]
elif len(L) == 2:
if isinstance(L[0], list):
firstMax = find_max(L[0])
else:
firstMax = L[0]
if isinstance(L[1], list):
lastMax = find_max(L[1])
else:
lastMax = L[1]
if firstMax > lastMax:
return firstMax
else:
return lastMax
else:
if isinstance(L[0], list):
firstMax = find_max(L[0])
lastMax = find_max(L[1:])
if firstMax > lastMax:
return firstMax
else:
return lastMax
else:
lastMax = find_max(L[1:])
if L[0] > lastMax:
return L[0]
else:
return lastMax
This will find the maximum in a list which contains nested lists and ignore string instances.
A = [2, 4, 6, 8, [[11, 585, "tu"], 100, [9, 7]], 5, 3, "ccc", 1]
def M(L):
# If list is empty, return nothing
if len(L) == 0:
return
# If the list size is one, it could be one element or a list
if len(L) == 1:
# If it's a list, get the maximum out of it
if isinstance(L[0], list):
return M(L[0])
# If it's a string, ignore it
if isinstance(L[0], str):
return
# Else return the value
else:
return L[0]
# If the list has more elements, find the maximum
else:
return max(M(L[:1]), M(L[1:]))
print A
print M(A)
Padmal's BLOG
If the nesting is arbitrarily deep, you first need recursion to untangle it:
def items(x):
if isinstance(x, list):
for it in x:
for y in items(it): yield y
else: yield x
Now, max(items(whatever))
will work fine.
In recent releases of Python 3 you can make this more elegant by changing
for it in x:
for y in items(x): yield y
into:
for it in x: yield from it
You are assuming given_list has at least 1 element which is incorrect. To avoid index out of range, you may add
if (len(given_list) == 0)
return None
to the beginning of your function.
If you're confident that there will only be one level of nesting in there, you could do something like
def r_max(lst):
new_lst = []
for i in lst:
try:
new_lst.extend(i)
except TypeError:
new_lst + [i]
return max(new_lst)
But I'm not in love with that solution - but it might inspire you to come up with something nicer.
Two things I'd like to highlight about this solution, in contrast to yours:
type(largest) == type([])
, etc.) isn't considered idiomatic Python. It works, but one of the key points of Python is that it promotes duck typing/EAFP, which means that you should be more concerned with what an object can do (as opposed to what type it is), and that you should just try stuff and recover as opposed to figuring out if you can do it.max
. If you can make your input a non-nested list, then max
does the rest for you.that error indicates your index is out of range, which is the case with the first element of your example. The solution is not to iterate over lists of length zero:
def r_max (given_list):
largest = given_list[0]
while type(largest) == type([]):
largest = largest[0]
for element in given_list:
if type(element) == type([]):
# If the list is empty, skip
if(len(elemnt) == 0)
next
max_of_elem = r_max(element)
if largest < max_of_elem:
largest = max_of_elem
else: # element is not a list
if largest < element:
largest = element
return larges
while your at it, you might want to assert len(given_list)>0
or something equivalent.