Listas em Python: operações básicas

Listas em Python: operações básicas
Yan Orestes
Yan Orestes

Compartilhe

Introdução

Uma professora de matemática elaborou uma técnica de avaliação diferente, em uma tentativa de aumentar a interação entre os alunos para a próxima prova, a nota de todos seria a mesma, equivalente à média de todas as notas.

Todo esse processo seria feito por um sistema automático em Python. As notas dos alunos da sala avaliada foram arquivadas em uma estrutura de lista:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

A fórmula para calcular a média aritmética de uma lista de números é a soma dos números dividida pela quantidade de números. Precisamos, então, descobrir duas coisas: a soma das notas e a quantidade de notas.

Banner da Escola de Programação: Matricula-se na escola de Programação. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

Somando todos os elementos de uma lista

Para somar todos os elementos da lista, vamos começar inicializando nossa variável que conterá o resultado da soma das notas com o valor 0, indicando que a soma ainda não foi feita:

soma_das_notas = 0

Assim, uma abordagem que podemos seguir é através da iteração sobre as notas - para cada nota, soma-se seu valor à variável soma_das_notas, dessa forma:

for nota in notas:
    soma_das_notas += nota

print(soma_das_notas)

E o resultado da soma:

98.0

Funciona perfeitamente! Mas será que não há uma maneira mais simples de somar todos os elementos de uma lista?

Somando os elementos de uma lista com a função sum()

Somar todos os elementos de algum conjunto é uma tarefa bastante comum em programação. Sendo assim, o Python também tem uma função nativa dedicada ao cálculo da soma de todos os elementos de uma lista - a função sum()!

Vamos usar essa nova abordagem:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

# código omitido

soma_das_notas = sum(notas)
print(soma_das_notas)

Novamente, o resultado esperado:

98.0

Não só é mais simples usar a função sum() do que implementar um algoritmo de soma nós mesmos, como sua performance é muito melhor - um loop for é executado como bytecode Python interpretado, enquanto a função sum() é escrita puramente na linguagem C.

Agora que já sabemos a soma das notas, precisamos descobrir a quantidade delas.

Descobrindo o tamanho de uma lista com a função len()

A quantidade de notas é o tamanho da lista. Podemos, é claro, contar nós mesmos e armazenarmos essa contagem nossa em uma variável:

qtd_de_notas = 15

Tudo bem, mas essa abordagem seria problemática caso a lista mudasse de tamanho, ou até mesmo se a lista fosse maior (imagine contar número a número em uma lista de mais de 100 elementos!)

Se já trabalhamos com outras linguagens de programação, provavelmente vimos que geralmente há uma maneira nativa mais simples para se calcular o tamanho de uma lista. No Python isso não é diferente!

A função built-in len() retorna o comprimento de um objeto cuja classe implemente o [método len()](https://docs.python.org/3/reference/datamodel.html#object.__len__), como por exemplo uma string, ou, no nosso caso, uma lista. Vamos testá-la com nossas notas:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

#código omitido

qtd_de_notas = len(notas)
print(qtd_de_notas)

E o resultado é o esperado:

15

Calculando a média aritmética

Agora que temos os dois valores que precisávamos, vamos calcular a média utilizando a fórmula soma_dos_numeros / quantidade_de_numeros:

media_das_notas = soma_das_notas / qtd_de_notas
print(media_das_notas)

Agora já temos a média:

6.5333

O resultado foi divulgado aos alunos, que responderam com reclamações - a nota foi mais baixa do que o esperado.

Depois de uma análise das notas, descobrimos que a média estava sendo calculada com a nota 0 de dois alunos que faltaram no dia da prova, o que não era justo!

Precisamos, então, remover essas notas 0 de nossa lista e recalcular a média.

Removendo um elemento de uma lista com o método remove()

Agora que já temos nossa lista completa, como podemos remover um elemento de dentro dela? Para isso, o Python nos traz o método remove(), que recebe como parâmetro o valor que queremos remover de nossa lista. Vamos testar:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

notas.remove(0)
print(notas)

E o resultado:

[0, 9.0, 8.0, 5.0, 10.0, 7.0, 0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Ok! Conseguimos remover um dos 0, mas o outro ainda ficou. Por que será? Acontece que o método remove() remove apenas o primeiro elemento encontrado cujo valor é igual ao parâmetro passado, não todos os elementos com esse valor.

Precisamos, então, chamar o método remove() duas vezes? Tudo bem, isso daria certo, mas e se, em vez de duas, tivéssemos dez notas 0. Será que realmente precisaríamos repetir uma mesma linha de código dez vezes? Isso não parece o ideal.

Conhecendo o Python e lógica de programação, uma abordagem intuitiva para esse problema seria iterar sobre a lista com um loop for e remover o valor caso ele seja igual a 0, para não precisarmos nos preocupar com a quantidade de notas 0. Vamos tentar:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

for nota in notas:
    if nota == 0:
        notas.remove(nota)

print(notas)

E o resultado:

[0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Ué! De novo sobrou um 0! Por quê, dessa vez? Nesse caso, o que houve foi uma confusão entre o laço for e o método remove().

O for itera sobre os elementos de uma lista através do índice - ou seja, ele começa com o elemento na posição 0, passa pro elemento na posição 1 e assim por diante, até que o índice (a posição) atinja o comprimento da lista.

O método remove(), por sua vez, ao apagar um elemento, realoca os outros dentro da lista para que não haja um espaço vazio no lugar onde havia o elemento removido. Quando removemos um elemento da lista, a lista realmente diminui de tamanho!

Sabendo disso, vamos fazer uma simulação passo a passo para tentar entender o que aconteceu:

PRIMEIRO LOOP: índice = 0 lista = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

SEGUNDO LOOP: índice = 1 lista = [0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Note que o segundo 0 foi ignorado pelo for! Quando o for chegou no índice 1, onde estava esse 0 inicialmente, o 0 já havia sido realocado para o índice 0, resultando nesse problema.

Por isso, devemos sempre lembrar que é recomendável nunca alterar uma lista enquanto se itera sobre ela!

Precisamos de uma forma melhor de remover todas as ocorrências de um mesmo valor em uma lista.

Filtrando uma lista utilizando list comprehensions

Já conhecemos uma técnica no Python chamada de compreensão de lista. Como podemos usá-la para resolver nosso problema? Queremos uma lista com todos os valores da nossa lista de notas, contanto que o valor seja maior que 0.

Vamos lá, então:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

notas_validas = [nota for nota in notas if nota > 0]
print(notas_validas)

E agora sim:

[9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Enfim, basta recalcularmos a média com essa nova lista de notas:

media_valida = sum(notas_validas) / len(notas_validas)
print(media_valida)

Dessa vez, uma média melhor para os alunos:

7.538461538461538

Após a média ser calculada e arredondada para 7.5, a professora quis conferir se seu método de avaliação tinha sido efetivo - isto é, se a nota da sala realmente representava como os alunos tinham se saído na prova.

Para isso, ela precisava calcular quantos alunos tiraram a nota na média, com uma margem de diferença de 0.5 (ou seja, quantos alunos tiraram uma nota entre 7 e 8).

Contando elementos em uma lista com o método count()

Para contar quantas vezes um elemento aparece numa lista, podemos usar o método count() dessa forma:

qtd_de_setes = notas.count(7.0)
print(qtd_de_setes)

E o resultado:

3

Para de fato fazermos o que queremos precisamos usar o método com três valores - 7, 7.5 e 8:

qtd_alunos_na_media = notas.count(7.0) + notas.count(7.5) + notas.count(8.0)
print(qtd_alunos_na_media)

O resultado:

8

Certo! No nosso caso, essa solução com o count() funciona bem, porque sabemos que são apenas esses três valores (7.0, 7.5 e 8.0) que queremos.

Mas e se nossa lista tivesse, por exemplo, valores como 7.1, 7.2... e assim em diante até 8.0. Teríamos que fazer um count() para cada um desses valores? Parece complicado, não é?

Uma outra abordagem que poderia ser utilizada, que evitaria o problema de haver mais valores no intervalo que queremos contar, seria utilizar um laço for e armazenar o valor da contagem em uma variável, dessa forma:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

qtd_alunos_na_media = 0
for nota in notas:
    if 7.0 <= nota <= 8.0:
        qtd_alunos_na_media += 1

print(qtd_alunos_na_media)

Temos o mesmo resultado:

8

Juntando o que aprendemos do método sum() e de compreensão de lista, e sabendo que no Python a classe bool, que representa os tipos booleanos, herda da classe int (True é igual a 1 e False é igual a 0), podemos até fazer isso de uma forma bem mais sucinta:

notas = [0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

qtd_alunos_na_media = sum([7.0 <= nota <= 8.0 for nota in notas])
print(qtd_alunos_na_media)

Temos o mesmo resultado:

8

Conclusão

Nesse post pudemos ver a utilidade da listas, quando podemos usá-las e o que podemos fazer com elas.

Passamos por necessidades como remover todas as ocorrências de um valor na lista, somar todos os elementos da lista, saber o comprimento da lista e até remover todas as ocorrências de um elemento na lista, e conseguimos resolver uma a uma através de nossa lógica e das próprias funcionalidades do Python!

Para saber mais

Quer aprender mais sobre listas em Python? Dê uma olhada nos nossos outros posts no blog sobre o assunto e aprenda mais sobre adicionar elementos a uma lista, ordenar uma lista e até conheça a funcionalidade da compreensão de lista.

Além disso, pode ser legal dar uma lida na documentação das listas no Python, para conhecer mais possibilidades no tratamento delas.

Outro assunto muito interessante é como trabalhar com dicionários em Python.

Gostou do conteúdo? Está mais confiante para usar listas no Python, agora? Que tal aprender um pouco mais? Confira nossa formação Python para web e continue estudando!

Veja outros artigos sobre Programação