Reputation: 26315
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
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
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
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