RoadRunner
RoadRunner

Reputation: 26315

Max Margin of List python

I am trying to make a program that finds the maximum integer of a list, and the margin between the highest number and the second highest number. I want it to return these tuple values:

    >>>max_margin([5,6,4,3])
    (6, 1)

    >>>max_margin([8, -2, 8, -3])
    (8, 0)

    >>>maxmargin([2])
    (2, None)

    >>>maxmargin([])
    (None, None)

I have made code which accomplishes this, but It's not the best way to go about it. Here it is:

    def max_margin(int_list):

        if not int_list:
            return None, None

        else:
            maxnum = nextval = int_list[0]
            bymargin = None

            for i in intlist:

                if i > nextval:
                    nextval = i

                if i > maxnum:
                    tmp = nextval
                    nextval = maxnum
                    maxnum = tmp

                    bymargin = maxnum - nextval

                if maxnum == i and nextval == i:
                    maxnum = i
                    nextval = i
                    bymargin = maxnum - nextval

                if len(int_list) <= 1:
                    maxnum = maxnum
                    bymargin = None

        return maxnum, bymargin

Is there a better way to write this?

Upvotes: 0

Views: 423

Answers (3)

Vince
Vince

Reputation: 336

You can do like this, int_list2 is not needed if you don't care about what happens to int_list.

def max_margin(int_list):
    if len(int_list)==0:
        return None,None
    if len(int_list)==1:  
        return int_list[0],None  
    max_val = max(int_list)
    int_list2 = list(int_list)
    int_list2.remove(max_val)
    max_val2 = max(int_list2)
    return max_val,max_val-max_val2

Upvotes: 0

Muhammad Tahir
Muhammad Tahir

Reputation: 5174

You can sort the list first to make it easy.

In [1]: def max_margin(int_list):
   ...:     args = sorted(int_list)
   ...:     try:
   ...:         return (args[-1], args[-1] - args[-2])
   ...:     except IndexError:
   ...:         try:
   ...:             return (args[-1], None)
   ...:         except IndexError:
   ...:             return (None, None)
   ...:         

In [2]: maxmargin([5,6,4,3])
Out[2]: (6, 1)

In [3]: maxmargin([8, -2, 8, -3])
Out[3]: (8, 0)

In [5]: maxmargin([2])
Out[5]: (2, None)

In [6]: maxmargin([])
Out[6]: (None, None)

Upvotes: 1

miradulo
miradulo

Reputation: 29690

A rather straightforward O(Nlog(N)) solution could involve just sorting the list.

def maxmargin(my_list):
    largest, secondlargest = sorted(my_list,reverse=True)[:2]
    return largest, largest - secondlargest

Else if runtime is of great importance you could have an O(N) solution by iterating only once, like so (credit to this solution for inspiration for second largest)

def max_margin(my_list):
    count = 0
    largest = second_largest = float('-inf')
    for x in my_list:
        count += 1
        if x > second_largest:
            if x >= largest:
                largest, second_largest = x, largest
            else:
                second_largest = x
    return largest, largest - second_largest if count >= 2 else None

Upvotes: 1

Related Questions