I am trying to make a function which return max from nested list?

后端 未结 6 1651
无人及你
无人及你 2021-01-24 08:48

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?

相关标签:
6条回答
  • 2021-01-24 09:27

    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
    
    0 讨论(0)
  • 2021-01-24 09:34

    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

    0 讨论(0)
  • 2021-01-24 09:36

    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
    
    0 讨论(0)
  • 2021-01-24 09:42

    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.

    0 讨论(0)
  • 2021-01-24 09:42

    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:

    1. All the type-checking you're doing (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.
    2. Python has a perfectly good "find the largest number in a list" function - max. If you can make your input a non-nested list, then max does the rest for you.
    0 讨论(0)
  • 2021-01-24 09:48

    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.

    0 讨论(0)
提交回复
热议问题