Kontrol Ego
Kontrol Ego

Reputation: 43

Find the second largest number in a list of numbers using python3

I know there are answers to this question, but the problem I am having with my code is that it works for most occasions except when it prints out the max number. As long as the first two numbers or more in the list are the max. It may sound confusing, but here's my code with an example.

def s_max(l):
    pos = 0
    m1 = max(l)
    m2 = 0
    for i in l:
        pos += 1
        if i > m2 and i != m1:
            m2 = i
        elif m2 == 0 and i == m1 and pos > 1:
            m2 = m1
        elif i < m1 and i <= m2:
            i = m2
        else:
            m2 = m2
    print(m2)

s_max([10,10,9])

OUTPUT = 10

When I use a list of numbers such as [9,10,10], the code will output 9.

Upvotes: 1

Views: 1986

Answers (5)

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11665

you can find the second largest number by sorting

>>> l = [1, 9, 8, 5, 2, 1, 7]
>>> second_largest_number = sorted(l)[-2]
>>> print(second_largest_number)
Output: 8

You can use below function without using sorting

def f(l):
  a = l[0]
  b = l[0]
  for i in l:
    if i > a and i > b:
       b = a
       a = i
    elif i > b:
       b = i
    elif b == a:
       b = i
  return b

>>> l = [1, 9, 8, 5, 2, 1, 7]
>>> f(l)
Output: 8

Upvotes: 0

khelili miliana
khelili miliana

Reputation: 3822

Way did not use just sorted and set :

l=[9, 10, 10, 11, 12, 12, 11]
sorted(set(l))[-2]

Output :

11

Upvotes: 0

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48067

You may create a generic function to get the nth largest number via creating a function using sorted() with set() as:

def get_n_largest(num_list, n):
    return sorted(set(num_list))[-n]

Sample run:

>>> get_n_largest([9,10,10], 2)
9

Upvotes: 1

niemmi
niemmi

Reputation: 17263

On the first iteration of the for loop just before the if-else block is executed your variables have following values:

m1 = 10
m2 = 0
i = 10
pos = 1

This means that the final else branch gets executed and since it sets m2=m2 nothing changes.

On the second iteration before if-else values are the same except that pos = 2. Now this causes the second branch to execute:

elif m2 == 0 and i == m1 and pos > 1:
    m2 = m1

There you set m2 to maximum you already found. On the third iteration third branch in if-else block get executed which changes nothing since you just assign value to loop variable.

All in all your code fails in case that two first values are the maximum items on the list. With minimal modifications you could just set the m2 if i is greater than current m2 but less than maximum value:

def s_max(l):
    m1 = max(l)
    m2 = 0
    for i in l:
        if m2 < i < m1:
            m2 = i

    print(m2)

If you don't want to write your own function you can use heapq.nlargest:

>>> import heapq
>>> l = [10, 10, 9]
>>> heapq.nlargest(2, set(l))[1]
9

Note that above assumes that there are two unique values on your list.

Upvotes: 0

Taku
Taku

Reputation: 33714

You can try doing this:

def s_max(l):
    while 1:
        val=max(l)
        l.remove(val)
        if val not in l: break
    return max(l)
output=s_max([10,10,9])
print(output) #prints 9

Upvotes: 1

Related Questions