Pular para o conteúdo

Fundamentos

Por que repetir: introdução aos laços em Python

Entenda o que é um laço em Python, as três perguntas que todo laço responde, como acompanhar as voltas na mão e por que um laço pode nunca terminar.

Por Prof. Rodrigo Faustino · Atualizado em · 15 min de leitura

Um laço é a estrutura que manda o computador repetir um bloco de código enquanto uma condição valer, ou uma vez para cada item de um grupo. O Python tem duas formas, o while ("enquanto") e o for ("para cada"), e as duas respondem à mesma pergunta: como fazer a mesma coisa muitas vezes sem escrever o código muitas vezes. Todo laço precisa decidir três coisas, que são o que repetir, quando parar e o que muda a cada volta. Quando alguma das três falta, o programa para de se comportar: ou repete de menos, ou repete para sempre.

Este é o primeiro artigo do módulo de repetição. Ele não ensina toda a sintaxe do while e do for, que ficam para os dois próximos artigos. O objetivo aqui é entender a ideia: por que um laço existe, como ler um laço volta por volta, quais variáveis aparecem em quase todos eles e onde estão os erros que mais prendem os alunos.

O problema: copiar e colar não escala

Imagine uma contagem regressiva de 5 até 1 seguida de uma mensagem final. Com o que já foi visto na série, o programa sai direto:

print(5)
print(4)
print(3)
print(2)
print(1)
print("fogo!")

A saída é 5, 4, 3, 2, 1 e fogo!, uma por linha. O programa funciona, e para cinco números é aceitável. Agora considere três pedidos de mudança. O primeiro é contar a partir de 10, o que exige reescrever as cinco linhas e acrescentar mais cinco. O segundo é que o usuário escolha de onde a contagem começa: o programa só saberá o número quando alguém digitar, e nenhum print escrito de antemão cobre isso. O terceiro é contar de 1000 até 1.

Os três pedidos mostram os limites de copiar e colar. O código cresce junto com o número de repetições, um erro de digitação vira um erro em cada cópia, e, no caso do usuário, o número de repetições só é conhecido em tempo de execução. A solução é escrever o bloco uma vez e dizer ao Python quantas vezes, ou até quando, ele deve rodar.

FastTeacherPara professores

Da ementa ao semestre planejado

  • Plano de ensino e calendário montados sozinhos
  • Diário de aulas pronto para colar no SIGA
  • Slides e listas de exercícios com gabarito
Conhecer o FastTeacher

Versão Community grátis · Windows

A ideia: dar voltas até a condição acabar

Pense numa pessoa lavando a louça. Ela não tem 40 instruções escritas ("lave o prato 1, lave o prato 2..."), e sim uma regra: enquanto houver prato sujo na pia, pegue um, lave e coloque no escorredor. A regra tem uma pergunta no início ("ainda há prato sujo?"), uma ação que se repete e uma coisa que muda a cada volta (um prato a menos na pia). Quando a pia esvazia, a pergunta dá "não" e a pessoa passa para a próxima tarefa.

O while é essa regra escrita em Python:

n = 5
while n >= 1:
    print(n)
    n = n - 1
print("fogo!")

A saída é a mesma de antes: 5, 4, 3, 2, 1 e fogo!. Mas agora, mudar para uma contagem de 1000 até 1 é trocar um número. A palavra while abre o laço, seguida da condição e dos dois-pontos, como no if. O bloco recuado embaixo é o que se repete, e o recuo funciona do mesmo jeito que no artigo sobre if e else: a primeira linha sem recuo, o print("fogo!"), está fora do laço e só roda depois que ele termina.

Fluxograma de uma contagem regressiva. Começa com n igual a 5 e chega a um losango com o teste n maior ou igual a 1. Se for True, segue para print(n) e depois n igual a n menos 1, e uma seta volta ao losango. Se for False, a seta sai para print fogo, depois do laço. À direita, uma tabela com seis testes: com n de 5 a 1 o resultado é True e o programa imprime o valor, e no sexto teste, com n igual a 0, o resultado é False e o laço termina.
O laço while volta ao teste depois de cada volta e só sai quando a condição dá False.

A figura acompanha o programa. O teste n >= 1 é feito antes de cada volta. Enquanto ele for verdadeiro, o programa imprime n, diminui n em 1 e volta ao teste. Na sexta vez que o teste é feito, n vale 0, a condição dá False, o programa pula o bloco recuado e segue para a linha seguinte. O laço faz cinco voltas, mas o teste acontece seis vezes, uma a mais que as voltas, e esse detalhe importa nos erros mais adiante.

As três perguntas de todo laço

À esquerda, o código de uma contagem regressiva: n igual a 5, while n maior ou igual a 1, print(n) e n igual a n menos 1 recuados, e um print final. À direita, três quadros ligados às linhas por setas: 1, quando parar, ligado à condição do while; 2, o que repetir, ligado ao bloco recuado com print; 3, o que muda a cada volta, ligado à linha n igual a n menos 1. Uma faixa pede que se responda as três perguntas antes de escrever um laço.
As três perguntas de todo laço: quando parar, o que repetir e o que muda a cada volta.

Quem escreve um laço sem pensar nele costuma errar um destes três pontos, e por isso vale respondê-los antes de digitar:

  1. Quando parar? É a condição do while. Ela diz "enquanto isto for verdade, faça mais uma volta". Na contagem, é n >= 1.
  2. O que repetir? É o bloco recuado. Só as linhas com recuo fazem parte do laço. Na contagem, é o print(n) e a atualização de n.
  3. O que muda a cada volta? Alguma coisa precisa mudar, senão a condição nunca fica falsa. Na contagem, o n começa em 5 e diminui 1 por volta. É a variável de controle do laço, e ela precisa de um valor inicial antes do while, o n = 5 da primeira linha.

Repare que a terceira pergunta tem duas partes: de onde a variável parte e como ela anda. Contadores crescem (i = i + 1, ou a forma curta i += 1 do artigo sobre operadores aritméticos), mas podem diminuir, como o n da contagem regressiva, ou andar de dois em dois, ou dobrar a cada volta.

Duas ferramentas para o mesmo trabalho

O while é a ferramenta geral: serve quando a única coisa que se sabe é a condição de parada. Quando o programa já sabe o que quer percorrer, como "os números de 1 a 5" ou "cada dia da semana", o for faz o mesmo trabalho com menos linhas e sem a variável de controle explícita:

for n in range(5, 0, -1):
    print(n)
print("fogo!")

A saída é a contagem de 5 a 1 e fogo! de novo. O range(5, 0, -1) produz os números de 5 até 1, descendo de 1 em 1: o 5 é onde começa, o 0 é onde ele para (sem incluí-lo) e o -1 é o passo. O for pega a variável n e a atualiza sozinho em cada volta. O artigo sobre o range() detalha os três números dessa função, e o artigo do while mostra o teste no início com mais casos. Por ora, a regra de bolso é que o for cabe quando o número de voltas é conhecido ao escrever o laço, e o while cabe quando o fim depende de algo que o programa só descobre rodando.

Os exemplos dos artigos anteriores já usaram o for em cima de uma sequência de valores, como for nota in (10, 9, 8.5). É o mesmo mecanismo: em vez de range, o laço percorre os itens de um grupo, um por volta.

FastMindAssistente de IA local

A IA que lembra da sua vida e mora no seu computador

  • Memória de longo prazo com a fonte de cada resposta
  • Funciona offline: seus dados ficam no seu PC
  • Lê PDFs, slides, fotos e gravações de reunião
Baixar grátis para Windows

Plano Essencial grátis para sempre

Acompanhar o laço na mão

À esquerda, o código que soma de 1 a 4 com um while. À direita, uma tabela de acompanhamento com uma linha por volta: na volta 1, i vale 1 e a soma depois fica 1; na volta 2, i vale 2 e a soma é 3; na volta 3, a soma é 6; na volta 4, a soma é 10 e i passa a valer 5. A última linha é o teste com i igual a 5, que dá False, e o programa imprime total 10.
Tabela de acompanhamento: uma linha por volta, com o valor de cada variável.

Existe um jeito de entender qualquer laço: fazer o trabalho do Python no papel. Cada linha da tabela é uma volta, e cada coluna é uma variável. O exemplo soma os números de 1 a 4:

soma = 0
i = 1
while i <= 4:
    soma = soma + i
    print(soma)
    i = i + 1
print("total", soma)

A saída é 1, 3, 6, 10 e total 10. A tabela da figura mostra o que a saída esconde. Na primeira volta, i vale 1 e soma passa de 0 para 1. Na segunda, i vale 2 e a soma vai a 3. Na terceira, 6; na quarta, 10, e i passa a valer 5. O teste seguinte, 5 <= 4, dá False, e o laço termina com o total 10 impresso depois.

Dois papéis aparecem aqui em quase todo laço:

  • Contador: uma variável que conta voltas ou ocorrências, como i. Começa num valor conhecido (0 ou 1) e anda um passo por volta.
  • Acumulador: uma variável que junta resultados, como soma. Começa no valor neutro da operação e recebe algo novo a cada volta.

O valor neutro é a escolha que mais gera erros. Para somar, o neutro é 0, porque somar 0 não muda nada. Para multiplicar, o neutro é 1:

soma = 0
produto = 1
for n in (2, 3, 4):
    soma = soma + n
    produto = produto * n
print(soma, produto)
errado = 0
for n in (2, 3, 4):
    errado = errado * n
print(errado)

A saída é 9 24 e 0. A soma de 2, 3 e 4 é 9, e o produto é 24. Se o acumulador do produto começa em 0, o resultado é 0 em qualquer caso, porque 0 vezes qualquer coisa é 0, e o programa não reclama de nada. A defesa é a tabela de acompanhamento: a primeira linha, antes da primeira volta, mostra o valor inicial, e quem vê 0 * 2 = 0 percebe o problema.

Quando ninguém sabe quantas voltas

O while faz mais falta quando o número de voltas depende do usuário. Um programa que soma valores até alguém digitar 0 não sabe, ao começar, se serão três ou trinta números. O zero funciona como sentinela, um valor combinado que significa "acabou":

total = 0
n = int(input("Valor (0 para parar): "))
while n != 0:
    total = total + n
    n = int(input("Valor (0 para parar): "))
print("total", total)
Valor (0 para parar): 10
Valor (0 para parar): 25
Valor (0 para parar): 5
Valor (0 para parar): 0
total 40

A leitura aparece duas vezes de propósito. A primeira, antes do laço, dá o valor inicial para o teste. A segunda, no fim do bloco, é o que muda a cada volta: sem ela, o n nunca mudaria e o laço não terminaria. Se o primeiro valor digitado já é 0, o laço não roda nenhuma vez e o total fica em 0, o que é a resposta certa para "somar nenhum valor". Esse é um ponto que o while tem e o for não tem: o teste vem antes da primeira volta, e por isso o laço pode rodar zero vezes.

O int() converte o texto digitado em número, e o != compara com o valor combinado, como no artigo sobre conversão de tipos. O desafio Até zero pede exatamente esse formato.

O laço que nunca termina

Se a condição nunca dá False, o laço não para. É o erro mais conhecido da repetição, e basta esquecer a atualização da variável:

i = 1
while i <= 3:
    print(i)

Nada no bloco muda o i, então i <= 3 é verdadeiro na primeira volta, na segunda, na milésima. O programa imprime 1 sem parar. No Python do computador, ele só termina quando alguém interrompe com Ctrl+C. No simulador, um laço assim não trava a página: a execução é cortada por contagem de instruções, e o botão de parar também funciona. Na placa, a interrupção também sai por Ctrl+C no terminal, ou pelo botão de reset, como o artigo sobre os primeiros passos com MicroPython explica.

Um laço infinito nem sempre é um erro. Um programa de ESP32 normalmente tem um while True: no arquivo main.py, que lê sensores, decide e age, para sempre ou até o aparelho ser desligado. A condição True é sempre verdadeira, e é isso mesmo que se quer. O que muda é que o programador decidiu o infinito de propósito, e ele continua precisando cuidar do que roda dentro, tema do artigo sobre programar sem travar.

O que muda na ESP32

A estrutura do laço é a mesma no MicroPython. Dois pontos pedem atenção. O primeiro é o uso comum em hardware: repetir uma ação um número fixo de vezes, como piscar um LED três vezes:

from machine import Pin
import time
led = Pin(2, Pin.OUT)
for vez in range(3):
    led.value(1)
    print("pisca", vez + 1, "ligado")
    time.sleep(0.5)
    led.value(0)
    print("pisca", vez + 1, "desligado")
    time.sleep(0.5)
print("fim")

A saída tem seis linhas, de pisca 1 ligado a pisca 3 desligado, e depois fim. O range(3) produz 0, 1 e 2, então o vez + 1 faz a contagem humana de 1 a 3. O time.sleep(0.5) pausa meio segundo entre cada mudança, sem o que o LED ligaria e desligaria rápido demais para o olho ver. Os detalhes de pinos e LEDs estão na ficha do ESP32 DevKit V1.

O segundo ponto é o float de 32 bits, que dá um defeito clássico de laços com decimais. Somar 0,1 dez vezes deveria dar 1:

x = 0.0
for i in range(10):
    x = x + 0.1
print(x, x == 1.0, x >= 1.0)
y = 0.0
voltas = 0
while y < 1.0 and voltas < 20:
    y = y + 0.1
    voltas = voltas + 1
print(voltas, y)

No simulador, a saída é 1.0000001 False True e 10 1.0000001. O 0,1 não existe exato em binário, e o erro de cada soma se acumula. Na versão de 32 bits, depois de 10 somas o valor passou de 1 por pouco, e o == dá False mesmo com a conta certa no papel. No Python do computador, com o float de 64 bits, o mesmo programa dá 0.9999999999999999 False False e o while faz 11 voltas, porque o valor ficou um pouco abaixo de 1 e o teste y < 1.0 ainda passou na décima volta. Os dois resultados diferem, e os dois estão "errados" para quem esperava 1. A defesa em laços é nunca usar == nem != com float como condição de parada: use < ou >=, conte as voltas com um inteiro (como o voltas do exemplo, que serve também de trava) ou trabalhe com inteiros.

Em sala de aula: onde os laços costumam tropeçar

Os casos abaixo se repetem nas turmas que chegam ao módulo de repetição. Em quase todos o Python não mostra erro nenhum, e o que aparece é um programa que faz outra coisa.

Esquecer de atualizar a variável

É o exemplo do i que nunca muda. O sintoma é a tela enchendo de linhas iguais, ou o programa que parece parado. A pergunta que resolve é a terceira das três: o que muda a cada volta? Se a resposta é "nada", o laço não termina.

Um a mais, um a menos

A diferença entre < e <= muda o número de voltas:

i = 1
while i < 5:
    print("menor", i)
    i = i + 1
print("---")
i = 1
while i <= 5:
    print("menor ou igual", i)
    i += 1
print("fim, i vale", i)

A saída tem quatro linhas menor (de 1 a 4), a separação, cinco linhas menor ou igual (de 1 a 5) e fim, i vale 6. Quem quer os números de 1 a 5 e usa < perde o 5, e quem usa <= com um limite errado ganha uma volta a mais. Repare também que, ao sair, i vale 6 e não 5, porque a última atualização acontece antes do teste que encerra. O teste na tabela de acompanhamento resolve isso com um olhar.

O recuo define o que está dentro do laço, como em qualquer bloco:

total = 0
for n in (10, 20, 30):
    total = total + n
print("total parcial", total)
print("---")
total = 0
for n in (10, 20, 30):
    total = total + n
    print("total parcial", total)

A saída é total parcial 60, a separação e depois total parcial 10, total parcial 30 e total parcial 60. O primeiro print está fora do laço e roda uma vez, no fim. O segundo está dentro e roda em cada volta. Nenhum dos dois dá erro, e qual é o certo depende do que a tarefa pede.

Zerar o contador dentro do laço

O valor inicial pertence antes do laço. Colocado dentro, ele volta ao início em cada volta e apaga o que foi acumulado:

n = 3
while n > 0:
    contador = 0
    contador = contador + 1
    n = n - 1
print(contador)

A saída é 1, e não 3. O programa deu três voltas, mas o contador = 0 desfez o progresso de cada uma. Um defeito parecido, com a variável de controle zerada dentro do laço, deixa o programa preso para sempre.

if no lugar de while

Quem acaba de aprender o if tende a usá-lo onde precisava de repetição:

n = 3
if n > 0:
    print("if roda uma vez", n)
    n = n - 1
print("---")
n = 3
while n > 0:
    print("while roda enquanto", n)
    n = n - 1

A saída é uma linha do if (if roda uma vez 3), a separação e três linhas do while, de 3 a 1. O if testa uma vez e segue em frente, enquanto o while volta ao teste depois de cada volta. É a mesma sintaxe de condição e dois-pontos, e por isso a troca passa despercebida.

O valor inicial neutro errado

O produto que começa em 0, mostrado antes, é o caso clássico, e o mesmo vale para a menor nota que começa em 0 ou o maior número que começa em 0 e nunca encontra um número negativo. Em cada caso, a pergunta é: qual valor não interfere no resultado desta operação?

Exercício: os gastos da semana

Uma pessoa anotou o que gastou em cada dia da semana: 35, 80, 12, 64, 0, 95 e 41 reais. O programa deve calcular o total, contar em quantos dias o gasto passou de 50 reais e mostrar a média diária. É um exercício de acumulador, de contador e de decisão no mesmo laço, e a média só pode ser calculada depois que o laço termina.

gastos = (35, 80, 12, 64, 0, 95, 41)
total = 0
caros = 0
for g in gastos:
    total = total + g
    if g > 50:
        caros = caros + 1
print("total", total)
print("dias acima de 50:", caros)
print("media", total / len(gastos))

A saída é total 327, dias acima de 50: 3 e media 46.714288. O total é o acumulador e começa em 0. O caros é o contador e só anda quando o if é verdadeiro, o que mostra que um laço pode ter decisões dentro dele. O len(gastos) conta quantos valores há, 7, e a divisão fica fora do laço, com o recuo na margem. O valor 46.714288 é o que o simulador mostra com o float de 32 bits, e o Python do computador mostraria 46.714285714285715. Os dois concordam até a quinta casa decimal.

Para treinar, mude o limite de 50 para 30 e confirme na tabela de acompanhamento que o contador sobe para 5.

Perguntas frequentes

Qual laço é melhor, while ou for?

Nenhum é melhor em geral. O for é mais curto quando o programa sabe o que percorrer, e o while é necessário quando o fim depende de algo que só aparece rodando, como a entrada do usuário ou uma leitura de sensor.

Um laço pode rodar zero vezes?

Pode. Se a condição do while já é falsa na primeira vez, o bloco não roda nenhuma vez. Se o for percorre um grupo vazio, também não.

Posso colocar um laço dentro de outro?

Pode, e é comum, como nas tabuadas. Cada laço de dentro roda completo a cada volta do laço de fora. Os artigos seguintes mostram o uso com calma.

O que é i += 1?

É a forma curta de i = i + 1. Existe uma versão para cada operador, como -= e *=. O Python não tem i++.

O que é while True?

É um laço com uma condição que nunca fica falsa. Ele só termina por um break (assunto de um artigo adiante) ou quando o programa é interrompido. Na ESP32 é o formato do laço principal.

Para continuar

A trilha Lógica com Python tem desafios de repetição. A Regressiva de 5 a 1 e a Tabuada do 2 são o primeiro contato, a Soma de 1 a 10 pede um acumulador, e o Até zero usa a sentinela. Se a condição do while ainda gera dúvida, releia o artigo sobre if, elif e else, que usa a mesma forma de teste.

O próximo assunto é o while em detalhe: o teste no início, os padrões de contador, acumulador e sentinela, e como escrever um laço que termina sempre.

Para praticar no PyPlaca

Trilhas

Lições

Fichas de componentes

FastMindAssistente de IA local

A IA que lembra da sua vida e mora no seu computador

  • Memória de longo prazo com a fonte de cada resposta
  • Funciona offline: seus dados ficam no seu PC
  • Lê PDFs, slides, fotos e gravações de reunião
Baixar grátis para Windows

Plano Essencial grátis para sempre

FastTeacherPara professores

Da ementa ao semestre planejado

  • Plano de ensino e calendário montados sozinhos
  • Diário de aulas pronto para colar no SIGA
  • Slides e listas de exercícios com gabarito
Conhecer o FastTeacher

Versão Community grátis · Windows

FastMindAssistente de IA local

A IA que lembra da sua vida e mora no seu computador

  • Memória de longo prazo com a fonte de cada resposta
  • Funciona offline: seus dados ficam no seu PC
  • Lê PDFs, slides, fotos e gravações de reunião
Baixar grátis para Windows

Plano Essencial grátis para sempre