2

First line contains N. Second line contains list of N integers each separated by a space. I need to find the second largest number in list.

My code:

N = int(raw_input())
L = map(int, raw_input().split())

for i in L:
    if i == max(L):
        L.remove(i)
print L
print max(L)
       

If input is [2, 6, 9, 9, 5], this still prints maximum value: 9, as only one 9 is getting removed from the list.

So, how to remove all the 1st maximum values in the list?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
SpaceOddity
  • 371
  • 3
  • 9
  • 20
  • 1
    Possible minor variation of [this](http://stackoverflow.com/questions/3628718/find-the-2nd-largest-element-in-an-array-with-minimum-of-comparisom). – Ami Tavory May 21 '15 at 19:13

6 Answers6

7

The reason that it's still returning 9 is because you're mutating the list as you iterate over it. Essentially the steps are:

1.    2  6  9  9  5
      ^idx0
2.    2  6  9  9  5
         ^idx1
3.    2  6  9  9  5
            ^idx2
  3a. 2  6  9  5
            ^idx2
4.    2  6  9  5
               ^

See how it skips evaluating the second 9 when it deletes the first 9? You'll notice if your list is [2, 6, 9, 5, 9], it works appropriately.

The minimal change to your code that will make it function is to iterate over a copy of the list, rather than the list itself.

L = [2, 6, 9, 9, 5]

maxL = max(L)  # gotta move this out!!
for i in L[:]:  # the slice creates a copy
    if i == maxL:
        L.remove(i)

print(max(L))

However it's probably easier to make a set (ensuring uniqueness), sort it, and return the second-to-last entry.

second_max = sorted(set(L))[-2]
Taufiq Rahman
  • 5,600
  • 2
  • 36
  • 44
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
5

try

N = 5
L = map(int, "2 6 9 9 5".split())

maxL = max(L)
#list comprehension for remove all occurrences of max(L)
L_filter = [e for e in L if e!=maxL]
print L
#print max of L_filter, second maximum of L
print max(L_filter)

you get:

[2, 6, 9, 9, 5]
6
Jose Ricardo Bustos M.
  • 8,016
  • 6
  • 40
  • 62
4

Remove duplicated elements by converting to a set:

values = set(L)

Then remove the maximum:

values.discard(max(values))
Roberto Bonvallet
  • 31,943
  • 5
  • 40
  • 57
  • seems like if you're going to do `max(values)` twice you may as well just do `sorted(set(L))[-2]`! – Adam Smith May 21 '15 at 19:24
  • @Adam That's exactly how I would do it because it is simpler, but one could argue that sorting is O(n log n) while computing the maximum twice is still O(n). – Roberto Bonvallet May 21 '15 at 19:28
0

you could also do this

L = [2, 6, 9, 9, 5]
L_tuples = zip(L, range(len(L))) #need tuples to make a dict
L_map = dict(L_tuples)           #use the dict to dedupe
L_uniq = L_map.keys()            #get back deduped values
L_sorted = sorted(L_uniq)        #sort them ascending
second_largest = L_sorted[-2]    #second from last is second largest

#or, rolling all that up...
second_largest = sorted(dict(zip(L, range(len(L)))).keys())[-2]
Tommy
  • 580
  • 4
  • 7
  • 1
    or you can use a `set` instead of having to create a `dict`, of course. just showing other ways to dedupe in python – Tommy May 21 '15 at 19:32
0
>>> import heapq
>>> values = [2, 6, 9, 9, 5]
>>> heapq.heapify(values)
>>> heapq._heapify_max(values)
>>> value = top = heapq.heappop()
>>> while value == top:
...     value = heapq.heappop()
>>> print value
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
0

Here is another way to calculate the second maximum in a list. The code also considers the scenario that includes duplicate elements in the list.

number_of_elements=int(input('The number of elements in list\n'))

a=[]
for i in range(number_of_elements):
    a.append(int(input('enter the list elements')))


#Use built-in function to calculate the maximum

max_list=max(a)

print("The maximum element is ",max_list)

#Calculate the number of times the number occur

count_of_max_num=a.count(max_list)

b=a

if (count_of_max_num == 1):

    b.remove(max_list)
    second_max=max(b)
    print("The second largest number is", second_max, "The new list is" ,b)
else:
    for i in range(count_of_max_num):
        b.remove(max_list)
    print ("The second largest is" , max(b))
Gaurav Parashar
  • 1,347
  • 2
  • 19
  • 21