While the other answers work, there’s one detail I’d like to comment on.
They are calling max
several times, no need. To better understand, we will modify only a little the program:
def maior(notas):
print('procurando maior nota')
return max(notas)
aluno = ["alice", "bob", "carol", "dave", "eve"]
notas = [10, 7, 9, 10, 10]
maiores_notas = [aluno[i] for i in range(len(aluno)) if notas[i] == maior(notas)]
That is, I created another function that calls max
but also prints a message. The output is:
procurando maior nota
procurando maior nota
procurando maior nota
procurando maior nota
procurando maior nota
The function was called 5 times (one for each note). But this is redundant and unnecessary, as the list of notes will no longer be modified and therefore I only need to search once. The problem here is that max
goes through all the elements of the list to find the largest, and when you go through the same list several times without need, you are creating a variation of the call Shlemiel the Painter’s Algorithm (which is a jocose synonym for a "dumb algorithm").
Anyway, a better solution is to get the biggest just once, and then check the students who have this grade.
And as already suggested in another answer, you can use zip
to scroll through both lists at the same time:
alunos = []
notas = []
for _ in range(5):
alunos.append(input('Digite o nome do aluno: '))
notas.append(int(input('Digite a média final do aluno: ')))
maior_nota = max(notas) # agora eu só chamo max uma única vez
maiores_notas = [ aluno for aluno, nota in zip(alunos, notas) if nota == maior_nota ]
I used a range
to repeat the reading of the data 5 times (and I used the variable _
in the for
, which is a Python convention to indicate that the variable is not used in loop - I just want to repeat something 5 times, but I won’t use the variable in the iteration).
I also renamed the lists to alunos
and notas
(both plural), since they will hold several students and grades respectively. It may seem like a minor detail, but give names better help when programming.
Of course, for small lists the difference will be insignificant, and if it’s just an exercise, maybe it’s just micro-optimization. But run several times to larger lists and you will begin to make a considerable difference. Remember that for few data, everything is fast.
Doing a test with the module timeit
, we can see the difference:
from timeit import timeit
from random import choices
chamar_uma_vez = "maior_nota = max(notas)\nmaiores_notas = [ aluno for aluno, nota in zip(alunos, notas) if nota == maior_nota ]"
chamar_varias_vezes = "maiores_notas = [ aluno for aluno, nota in zip(alunos, notas) if nota == max(notas) ]"
qtd = 1000
alunos = list(range(qtd)) # cria uma lista com 1000 elementos
notas = choices(range(11), k=qtd) # cria uma lista com 1000 notas aleatórias entre 0 e 10
execucoes = 1000 # executar mil vezes cada um
# imprime o tempo em segundos para cada um dos algoritmos
print(timeit(stmt=chamar_uma_vez, number=execucoes, globals=globals()))
print(timeit(stmt=chamar_varias_vezes, number=execucoes, globals=globals()))
First, it is worth remembering that times can vary from one machine to another, because it depends on several factors, such as the hardware, if there were other things running on the machine, etc.
But anyway, creating lists with 1000 students and 1000 grades, and running 1000 times each search, on my machine I got 0.07 seconds in the first solution (calling max
only once) and 21 seconds in the second solution (calling max
several times). That is, almost 300 times slower. I ran several times and the results did not vary much beyond that.
In the Repl.it times were different (around 0.3 to 0.4 seconds for the first solution and around 80 seconds for the second), but still we see that call max
several times was about 200 times slower.
Using lists with 10 notes, the difference is no longer so great (0.001 versus 0.005), but as I have already said, for small lists the difference is imperceptible. But that’s where the danger lies: you see that it "works" and you will only notice that there is a problem up front. Despite being "only an exercise", it is important to pay attention to these details from now on, so as not to think that any code that "works" is necessarily a good code.