I am trying to write code for finding the second maximum value of a list.
I tried it like this:
arr = map(int, input().split())
lista = list(arr)
max_value = lista[0]
run = lista[0]
for i in lista:
if max_value < i:
max_value = i
for j in lista:
if run < j and run < max_value:
run = j
print(run)
And the second maximum value and the maximum value comes out to be the same. What is the mistake in my program?
run = lista[0]
...
if run < j and run < max_value:
Should be
v
run = min(lista)
...
v
if run < j and j < max_value:
We can reduce the boilerplate of firsts lines by using a comprehension instead of a succession of map and list constructors:
arr = map(int, input().split())
lista = list(arr)
become:
lista = [int(n) for n in input().split()]
The next block of your logic is here to find the max of the list. You don't need to write this code yourself, you can ask Python. This will reduce the complexity of your code, making the issue/bug easier to spot.
max_value = lista[0]
for i in lista:
if max_value < i:
max_value = i
become:
max_value = max(lista)
To help our brain understand what happens, let's clarify variables names:
lista = [int(n) for n in input().split()]
max_value = max(lista)
run = lista[0]
for j in lista:
if run < j and run < max_value:
run = j
print(run)
become:
user_input = [int(n) for n in input().split()]
max_value = max(user_input)
second_max = user_input[0]
for current_value in user_input:
if second_max < current_value and second_max < max_value:
second_max = current_value
print(second_max)
Now, the code is smaller, easier to understand, with less place for error. If there is an error, we don't have to look at many places.
What's wrong? second_max
should be the 2nd maximum value, but it's not.
What could cause that? An update of previous_value
that shouldn't happen.
So this is where the issue might happen.
if second_max < current_value and second_max < max_value:
second_max = current_value
The attribution is correct, the condition should be wrong.
This seems correct second_max < current_value
since we want to update only if second_max
is lower than current_value (meaning that current might be the true second_max
value OR equal to max_value
.
So we need another condition: current_value
shouldn't be the max_value
, otherwise, second_max
might be set to the max_value
.
And, we look at the second condition: second_max < max_value
. Here is our mistake.
Let's fix the condition, since it's current_value
that should be lower than max_value
.
Also, the initial value of second_max
need to be set at the minimum value in case the first value is the max.
user_input = [int(n) for n in input().split()]
max_value = max(user_input)
second_max = min(user_input)
for current_value in user_input:
if second_max < current_value and current_value < max_value:
second_max = current_value
print(second_max) # 55
Done.
If you want the second maximum value in a list, it is easier to sort a de-duplicated list and print the element at index 1 of the list e.g. the second element.
without_duplicates = {int(n) for n in input().split()}
ordered_without_duplicates = sorted(without_duplicates, reverse=True)
print(ordered_without_duplicates[1])
print(sorted({int(n) for n in input().split()}, reverse=True)[1])
print(heapq.nlargest(2, {int(n) for n in input().split()})[1])