Pular para conteúdo

10. Padrões de lista

Nesta aula

Ideia central: quase tudo que você vai precisar fazer com uma lista este semestre cabe em cinco formas. Elas não são truque de decoração — são o vocabulário que a disciplina seguinte já vai supor que você conhece.

Ao fim você vai conseguir: somar todos os valores de uma lista; contar quantos atendem a uma condição; achar o maior ou o menor sem o candidato inicial que mente; separar para uma lista nova o que interessa; e construir, a partir de uma lista, uma lista nova de totais que crescem.

Cinco formas, uma lista só

Os três primeiros padrões já apareceram na Unidade 3 — acumulador, contador, extremo — só que ali eles processavam números que chegavam pelo teclado, um de cada vez. Agora a lista já existe inteira antes do laço começar, e dois padrões novos entram: os que não terminam num número, mas numa lista nova.

Padrão O que faz Nasce como
somar tudo acumulador sobre a lista inteira total = 0
contar sob condição contador com um if dentro do for contagem = 0
achar o maior/menor extremo, com candidato honesto = lista[0]
filtrar para lista nova guarda só quem passa no if = []
acumular em lista nova guarda um total que cresce a cada volta = [] e total = 0

A maior parte dos exemplos abaixo percorre o mesmo cenário — o consumo de dados de um cliente ao longo do mês. Dois trocam de domínio de propósito: o padrão 3 precisa de uma lista com valores negativos para expor o defeito, e o padrão 5 usa gastos em vez de consumo. Repare que a estrutura muda pouco de um padrão para o outro — é sempre um for, às vezes com um if dentro.

Padrão 1 · somar tudo

# Padrao 1: somar tudo -- acumulador percorrendo uma lista ja pronta.
consumo_gb = [4.2, 1.8, 5.0, 0.9, 3.3]

total = 0
for consumo in consumo_gb:
    total = total + consumo

print(f"Consumo total do mes: {total:.1f} GB")
Consumo total do mes: 15.2 GB

O mesmo acumulador do capítulo 7: total nasce em 0, antes do for, e cresce em toda volta. A única diferença é que agora ele soma os itens de uma lista pronta em vez de somar o que acabou de vir do input().

Padrão 2 · contar sob condição

# Padrao 2: contar sob condicao -- contador com um if dentro do for.
consumo_gb = [4.2, 1.8, 5.0, 0.9, 3.3]
meta = 3.0

dias_acima = 0
for consumo in consumo_gb:
    if consumo > meta:
        dias_acima = dias_acima + 1

print("Dias acima da meta:", dias_acima)
Dias acima da meta: 3

dias_acima nasce em 0 e só cresce dentro do if. Repare na diferença de uma linha para o padrão anterior: total = total + consumo soma o valor; dias_acima = dias_acima + 1 soma sempre 1, e só quando a condição é verdadeira.

Padrão 3 · achar o maior ou o menor

Este é o padrão em que a maioria das pessoas escreve algo que parece certo e está errado. O hábito mais comum é começar o candidato em 0:

maior = 0
for v in medicoes:
    if v > maior:
        maior = v

Funciona quando todos os valores são positivos — e é exatamente por isso que o defeito sobrevive sem ninguém notar. Ele aparece na primeira lista que tem só valores negativos:

# Padrao 3: o extremo -- o candidato inicial tem de ser HONESTO.
saldos = [-120.0, -35.0, -280.0, -60.0]

maior_errado = 0
for saldo in saldos:
    if saldo > maior_errado:
        maior_errado = saldo

maior_certo = saldos[0]
for saldo in saldos:
    if saldo > maior_certo:
        maior_certo = saldo

print("Maior saldo (comecando em 0):", maior_errado)
print("Maior saldo (comecando no primeiro):", maior_certo)
Maior saldo (comecando em 0): 0
Maior saldo (comecando no primeiro): -35.0

Os quatro saldos são todos negativos, o maior de verdade é -35.0 — e o laço que começa em 0 responde 0, um saldo que não existe na lista. O programa não travou, não avisou nada: só mentiu, com uma cara plausível de resposta certa.

Por que 0 não é um candidato honesto

0 não é "nenhum valor ainda" — é um valor real, e ele entra na disputa como se tivesse sido medido. Se a lista inteira for negativa, 0 vence sempre, porque é maior que qualquer um deles. Se você estivesse procurando o menor valor e começasse em 0, o defeito seria ainda mais traiçoeiro: numa lista de consumos, que nunca são negativos, menor = 0 venceria sempre — não é um erro que aparece de vez em quando, é um erro que acontece em toda execução, com qualquer entrada, e o resultado (0.0) sempre parece uma resposta plausível.

A correção é uma troca de uma linha: o candidato inicial é o primeiro item da própria lista, não um número inventado.

maior = medicoes[0]
for v in medicoes:
    if v > maior:
        maior = v

Agora o candidato inicial é um saldo que existe de verdade — o pior caso possível é o laço nunca achar nada melhor, e a resposta continuar sendo o próprio primeiro item. Nunca um valor de fora da lista.

💡 Pense assim: o primeiro concorrente já está classificado

Um campeonato não compara os atletas com "zero pontos" antes de começar: o primeiro que aparece já é o líder provisório, e só perde o posto para quem jogar melhor de verdade. Comparar com zero é inventar um concorrente que não existe — e que pode estar roubando o título de quem competiu.

Padrão 4 · filtrar para uma lista nova

Às vezes você não quer um número — quer separar os itens que interessam, mantendo o valor original de cada um.

# Padrao 4: filtrar para uma lista NOVA -- a lista original nao muda.
consumo_gb = [4.2, 1.8, 5.0, 0.9, 3.3]
meta = 3.0

acima_da_meta = []
for consumo in consumo_gb:
    if consumo > meta:
        acima_da_meta.append(consumo)

print("Consumos acima da meta:", acima_da_meta)
print("Quantos:", len(acima_da_meta))
Consumos acima da meta: [4.2, 5.0, 3.3]
Quantos: 3

acima_da_meta nasce [], e só recebe um item quando o if dá certo. É o padrão 2 (contador) com uma troca: em vez de somar 1, você append o valor inteiro. A lista original, consumo_gb, não muda em nada.

Padrão 5 · acumular numa lista nova

O último padrão junta um acumulador com uma lista nova: a cada volta, o total cresce e o valor dele naquele momento é guardado.

# Padrao 5: acumular numa lista NOVA -- um total que cresce, guardado a cada volta.
gastos = [50.0, 30.0, 20.0, 45.0, 15.0]

acumulado = []
total = 0
for gasto in gastos:
    total = total + gasto
    acumulado.append(total)

print("Saldo gasto acumulado:", acumulado)
Saldo gasto acumulado: [50.0, 80.0, 100.0, 145.0, 160.0]

acumulado guarda, em ordem, "quanto já tinha sido gasto até aqui" depois de cada dia — um saldo que cresce dia a dia, não só o total final. É a diferença entre "quanto gastei no mês" (um número, padrão 1) e "quanto eu já tinha gastado em cada dia do mês" (uma lista nova, padrão 5).

Os cinco lado a lado

Padrão Nasce Cresce quando Termina em
somar tudo total = 0 toda volta um número
contar sob condição contagem = 0 só quando o if é verdadeiro um número
achar o maior/menor = lista[0] só quando acha um melhor um número
filtrar para lista nova = [] só quando o if é verdadeiro uma lista
acumular em lista nova = [] e total = 0 toda volta uma lista

A pergunta que decide qual usar é sempre a mesma da Unidade 3, com uma adição: o que eu preciso no fim — um número ou uma lista?

Erros comuns deste capítulo

Mensagem ou sintoma Causa provável
o maior/menor deu um valor que não está na lista o candidato começou em 0 (ou outro número inventado) em vez de lista[0]
a lista filtrada veio vazia quando não devia o if está com a condição trocada, ou comparando com a variável errada
a lista nova ficou do mesmo tamanho da original, mas devia ser menor trocou filtrar (padrão 4, if antes do append) por acumular (padrão 5, append sempre)
o total dentro da lista acumulada está errado o append veio antes de somar o valor da volta
contagem e total deram o mesmo número um dos dois está somando o valor em vez de somar 1 (ou o contrário)

Resumo

  • Somar tudo: acumulador de sempre, agora sobre uma lista pronta.
  • Contar sob condição: contador que só cresce dentro de um if.
  • Achar o maior/menor: o candidato inicial tem de ser um valor que existe na lista — lista[0], nunca 0. É o erro que não dá erro desta unidade.
  • Filtrar para lista nova: append só quando o if é verdadeiro; a lista original não muda.
  • Acumular em lista nova: soma e append juntos, a cada volta — guarda o total como ele estava em cada momento, não só no fim.

Para praticar

Lista 10 · Padrões de lista.

Com estes cinco padrões você processa qualquer lista de números que este semestre vai te dar. A Unidade 5 troca o número pelo texto — e boa parte destes mesmos padrões volta a aparecer, agora percorrendo letras em vez de itens.