Pular para o conteúdo

Fundamentos

O laço while em Python: repetição com teste no início

Aprenda o laço while em Python: as quatro peças, os padrões de contador, sentinela e bandeira, as condições compostas e os erros que geram laços infinitos.

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

O while repete um bloco de código enquanto uma condição for verdadeira, e o teste acontece antes de cada volta, inclusive da primeira. Por isso o bloco pode rodar muitas vezes, uma vez ou nenhuma. Para o laço terminar, alguma coisa dentro dele precisa mudar o resultado do teste. Quando isso acontece, o programa sai do bloco e continua na primeira linha sem recuo; quando não acontece, o laço roda para sempre.

O artigo anterior mostrou por que os laços existem e quais perguntas todo laço responde. Este é dedicado ao while: as quatro peças que o formam, os três padrões que resolvem a maior parte dos problemas, as condições com and e not, o or que gera laços infinitos, o while dentro de outro e o uso na ESP32.

As quatro peças

À esquerda, um código de cinco linhas numeradas: i igual a 1 (1, valor inicial), while i menor ou igual a 5 (2, teste), print(i) (3, corpo), i mais igual a 1 (4, atualização) e print fim (5, depois). À direita, uma legenda explica cada peça. Abaixo, a ordem de execução: 1, depois 2, 3 e 4 cinco vezes, depois 2 e 5. Uma faixa avisa que o teste vem antes do corpo, então o corpo pode rodar zero vezes.
As quatro peças do while e a ordem em que o Python as executa.

Um while bem escrito tem quatro peças, e a figura as numera na ordem em que o Python as executa:

i = 1
while i <= 5:
    print("2 x", i, "=", 2 * i)
    i += 1
print("fim")

A saída é a tabuada do 2 até o quinto termo, de 2 x 1 = 2 a 2 x 5 = 10, e depois fim. As peças são:

  1. O valor inicial, i = 1, que fica antes do laço e cria a variável que o teste vai olhar.
  2. O teste, i <= 5, que o Python avalia antes de cada volta. Se der True, entra no bloco; se der False, pula para depois dele.
  3. O corpo, o print, que é o trabalho repetido.
  4. A atualização, i += 1, que muda a variável para que o teste, em algum momento, dê False.

A peça 5 da figura, o print("fim") sem recuo, não é do laço. Ela roda uma vez, quando o teste falha. Quem aprende o while costuma errar a posição de uma dessas peças: o valor inicial dentro do laço, a atualização fora dele, ou o teste que não olha a variável que muda.

O laço que não roda nenhuma vez

Como o teste vem antes do corpo, um while cuja condição já começa falsa não executa o bloco:

n = 0
while n > 0:
    print("nunca aparece")
    n = n - 1
print("o laco nao rodou, n vale", n)

A saída é só o laco nao rodou, n vale 0. Isso é uma característica útil, não um defeito: um programa que soma os valores digitados e recebe zero logo de início deve somar nada e responder 0, sem precisar de um if especial. O while com teste no início trata esse caso de graça. Existe outro tipo de laço, que roda o corpo antes de testar, e o Python não tem uma palavra própria para ele. O artigo sobre o "faça-enquanto" mostra como simulá-lo.

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

Três padrões que resolvem quase tudo

Três cartões lado a lado com um trecho de código cada. O padrão contador usa i igual a 1, while i menor ou igual a 5 e i mais igual a 1, e serve quando se sabe quantas voltas. O padrão sentinela lê n com input, repete enquanto n for diferente de 0 e lê de novo no fim do bloco, e serve quando o usuário decide quando parar. O padrão bandeira usa ligado igual a True, while ligado e muda ligado para False dentro de um if, e serve quando um estado decide. Uma faixa lembra que a linha que atualiza fica dentro do laço.
Três padrões de while: contador, sentinela e bandeira.

A maioria dos while que se escreve no começo cai num destes padrões. Reconhecer o padrão ajuda a escrever o laço sem tentativa e erro.

O contador

Quando se sabe quantas voltas dar, uma variável conta até o limite. É o padrão da tabuada acima: valor inicial, teste contra o limite e += 1 no fim do bloco. O contador pode crescer, diminuir (n -= 1) ou andar de dois em dois (i += 2), e o teste usa <, <=, > ou >= conforme o sentido. Para esse padrão, o for com range() costuma ser mais curto, e é o assunto do próximo artigo da série.

A sentinela

Quando é o usuário quem decide quando parar, o programa não sabe de antemão quantas voltas serão necessárias. Um valor combinado, a sentinela, avisa o fim. O exemplo calcula a média de notas, e o -1 encerra a lista:

soma = 0
contador = 0
nota = float(input("Nota (-1 para parar): "))
while nota != -1:
    soma = soma + nota
    contador = contador + 1
    nota = float(input("Nota (-1 para parar): "))
if contador > 0:
    print("media", soma / contador)
else:
    print("nenhuma nota")

Com as entradas 8, 6.5, 9 e -1, a última linha da saída é media 7.8333336. O Python do computador mostraria 7.833333333333333, a mesma conta com o float de 64 bits (o simulador usa 32 bits, como a placa). Se a primeira nota digitada já for -1, o laço não roda, o contador fica em 0 e o programa imprime nenhuma nota. O if contador > 0 existe por isso: sem ele, a divisão soma / contador seria uma divisão por zero. O desafio Média de N usa uma variação: o primeiro número lido diz quantos valores virão depois, e o laço é um contador.

Repare na leitura, que aparece duas vezes. A primeira, antes do laço, dá ao teste o valor com que comparar. A segunda, na última linha do bloco, é a atualização do padrão: ela é o que muda a cada volta. Quem escreve só a primeira leitura monta um laço que lê uma vez e repete para sempre o mesmo valor.

A bandeira

Às vezes o laço depende de um estado do programa, e não de um número. Uma variável booleana, a bandeira, guarda esse estado e vira False quando a repetição deve acabar:

carga = 100
ligado = True
while ligado:
    carga = carga - 30
    print("carga", carga)
    if carga <= 20:
        ligado = False
print("desligado com", carga)

A saída é carga 70, carga 40, carga 10 e desligado com 10. O while ligado: dispensa a comparação, porque ligado já é um booleano. Quem decide parar é o if dentro do corpo, e note que a volta em que a carga chega a 10 termina normalmente: o teste só é feito de novo no início da volta seguinte. Esse padrão aparece em jogos (a partida continua enquanto o jogador tiver vidas), em menus (o menu se repete enquanto o usuário não escolher sair) e em programas de placa (o aparelho funciona enquanto não houver erro).

Uma condição que consome o valor

Um quarto jeito é o laço em que a própria variável do teste vai sendo gasta. A contagem de dígitos de um número é o exemplo clássico, e usa a divisão inteira e o resto vistos no artigo sobre operadores aritméticos:

n = 4821
digitos = 0
soma = 0
while n > 0:
    soma = soma + n % 10
    n = n // 10
    digitos = digitos + 1
print(digitos, soma, n)

A saída é 4 15 0. O n % 10 pega o último algarismo, e o n // 10 o descarta. A cada volta o número encolhe: 4821, 482, 48, 4, 0. Quando ele chega a 0, o teste n > 0 falha. O programa contou 4 dígitos, somou 4 + 8 + 2 + 1 = 15 e deixou n zerado, o que mostra que o laço destrói o valor original. Se o número precisar ser usado depois, guarde uma cópia numa variável antes do laço.

Condições compostas: and, not e a conta de tentativas

A condição do while é uma expressão booleana como as do if, e aceita and, or e not. Um uso muito comum é combinar "ainda há tentativas" com "ainda não acertou", e o exemplo da senha mostra os dois:

tentativas = 0
acertou = False
while tentativas < 3 and not acertou:
    senha = input("Senha: ")
    tentativas = tentativas + 1
    if senha == "1234":
        acertou = True
    else:
        print("senha errada")
if acertou:
    print("acesso liberado")
else:
    print("bloqueado")

Com as entradas 1111 e 1234, o programa mostra senha errada e depois acesso liberado. Se as três senhas forem erradas (1111, 2222 e 3333), ele mostra senha errada três vezes e termina com bloqueado. O laço tem duas razões para parar, e cada uma é uma metade da condição: acabaram as tentativas ou o usuário acertou. O and exige que as duas continuem verdadeiras para repetir. Depois do laço, o if acertou descobre qual das duas razões encerrou a repetição, um truque que serve para qualquer laço com duas saídas. O desafio Senha 1234 é a versão mais simples dessa ideia, sem limite de tentativas: repete a leitura até a senha certa.

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

O erro do or

Uma tabela-verdade com as respostas s, n e x. As colunas mostram resp diferente de s, resp diferente de n, o resultado com or e o resultado com and. Com or, o resultado é True nas três linhas, então o laço nunca sai. Com and, o resultado é False para s e para n e True para x. Abaixo, o laço errado com or é mostrado em vermelho e o laço certo com and, ou com not in, em verde.
Com or a condição fica sempre verdadeira e o laço nunca termina; com and o laço repete só para respostas inválidas.

A pergunta "repita enquanto a resposta não for s nem n" é uma armadilha de lógica, e quase todo mundo a escreve errado pelo menos uma vez, porque a frase em português tem "nem" e o código pede and. A tabela da figura mostra a conta:

for resp in ("s", "n", "x"):
    print(resp, resp != "s" or resp != "n", resp != "s" and resp != "n", resp not in ("s", "n"))

A saída é s True False False, n True False False e x True True True. A segunda coluna, a do or, dá True nas três linhas. Quem digita s passa no teste resp != "n", e quem digita n passa no teste resp != "s", então nenhuma resposta faz o laço parar, nem a resposta certa. O and e o not in dão False para s e para n, e True só para a resposta inválida. A versão correta, com a mensagem de erro e a nova leitura dentro do laço, é esta:

resp = input("Continuar (s/n)? ")
while resp != "s" and resp != "n":
    print("Responda s ou n")
    resp = input("Continuar (s/n)? ")
print("resposta", resp)

Com as entradas x, q e s, a saída pede a resposta de novo duas vezes e termina com resposta s. É a mesma situação das tabelas-verdade: quando a condição parece certa mas o programa se comporta mal, monte a tabela com os valores possíveis. As leis de De Morgan, tratadas nesse artigo, explicam por que "não s e não n" é o mesmo que "não (s ou n)".

Um while dentro de outro

O corpo de um while pode conter outro while. O laço de dentro roda completo a cada volta do de fora, e o resultado é uma grade:

i = 1
while i <= 3:
    j = 1
    while j <= 3:
        print(i * j, end=" ")
        j += 1
    print()
    i += 1

A saída é a tabuada de 1 a 3 em três linhas: 1 2 3, 2 4 6 e 3 6 9. O end=" " troca a quebra de linha do print por um espaço, para os números ficarem lado a lado, e o print() vazio, no recuo do laço de fora, quebra a linha ao fim de cada fileira. Repare que o j = 1 fica dentro do laço de fora: ele precisa voltar a 1 em cada fileira. Esquecer isso, ou colocar o j = 1 antes dos dois laços, é o defeito clássico, porque na segunda fileira o j já vale 4 e o laço de dentro não roda nenhuma vez.

O que muda na ESP32

O while do MicroPython é o mesmo do Python do computador. Dois usos aparecem o tempo todo em programas de placa. O primeiro é o laço principal, o while True: do main.py, que lê sensores, decide e age até a placa ser desligada. Ele precisa de uma pausa com time.sleep ou time.sleep_ms dentro do corpo, senão roda o mais rápido que o processador deixar. O artigo sobre programar sem travar mostra como fazer várias tarefas dentro dele.

O segundo é esperar por algo com limite de tempo, uma espera com timeout. O teste compara o tempo que passou com um limite:

import time
inicio = time.ticks_ms()
voltas = 0
while time.ticks_diff(time.ticks_ms(), inicio) < 200:
    voltas = voltas + 1
    time.sleep_ms(50)
print("pelo menos 3 voltas:", voltas >= 3)

A saída é pelo menos 3 voltas: True. A função time.ticks_ms() devolve um contador de milissegundos, e time.ticks_diff calcula a diferença entre dois valores sem se confundir quando o contador dá a volta, o que o - simples não garante, como o artigo sobre ticks explica. O laço repete enquanto menos de 200 ms se passaram. O programa imprime só se houve pelo menos três voltas, e não o número exato, porque ele muda de uma execução para outra, e na placa também depende da velocidade da leitura. É a base de esperas como "aguarde a resposta do sensor por até dois segundos". Um laço de espera sempre precisa de uma saída por tempo, para a placa não ficar presa a um sensor que nunca responde.

Os laços com float pedem o cuidado do artigo anterior: comparar com == ou != um valor acumulado de 0,1 em 0,1 pode nunca dar certo, e uma contagem de voltas inteira como trava é a defesa mais simples.

Em sala de aula: onde o while costuma tropeçar

Os casos abaixo se repetem nas turmas, e os de laço infinito são os que mais chamam o professor. Em todos o programa roda, e o que falha é o comportamento.

A atualização fora do laço

A linha de atualização sai do recuo e o teste nunca muda:

i = 1
voltas = 0
while i <= 3 and voltas < 5:
    print("i vale", i)
    voltas += 1
i = i + 1
print("voltas", voltas, "i", i)

A saída tem cinco linhas i vale 1, depois voltas 5 i 2. O i = i + 1 está na margem, depois do laço, então roda uma vez só, no fim. O i fica em 1 durante todo o laço. Sem a trava do voltas, o programa imprimiria i vale 1 para sempre. A trava é uma boa prática de depuração: um contador de segurança que corta o laço no valor esperado mais uma folga.

O sinal de igual no teste

O = é atribuição e o == é comparação, e um while n = 0: não funciona. As mensagens variam:

ErroSimulador (MicroPython)Python no computador
while n = 0:SyntaxError: invalid syntax (linha 2)SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
while n > 0 sem os dois-pontosSyntaxError: invalid syntax (linha 2)SyntaxError: expected ':'
corpo sem recuoSyntaxError: invalid syntax (linha 3)IndentationError: expected an indented block after 'while' statement on line 2

O simulador diz só invalid syntax e a linha. A pista é olhar a linha indicada: o = onde devia haver ==, os dois-pontos que faltam no fim da linha do while e a linha seguinte que não está recuada. O artigo sobre if e else trata dos erros de recuo com mais detalhe.

A segunda leitura que não existe

No padrão da sentinela, quem lê o valor só antes do laço fica com um laço infinito: a variável do teste nunca muda. É o mesmo erro da atualização esquecida, com uma desculpa mais difícil de enxergar, porque o input() fica logo acima do while e dá a impressão de que a leitura "já está lá". A pergunta de teste é: onde, dentro do bloco, o valor de nota muda?

Esquecer o caso de zero voltas

A média sem nenhuma nota, a soma de uma lista vazia, a senha de um usuário que desiste antes de começar. Se o programa divide pelo contador, o if contador > 0 do exemplo da média existe para isso. O teste que vale fazer em todo while é a primeira volta já falsa.

O or no lugar do and

O erro da figura, com a tabela-verdade. A frase em português "enquanto não for s nem n" é um and, e o or produz um laço que nunca termina, e que passa sem nenhum aviso.

O j que não volta ao início

Em laços aninhados, a variável do laço de dentro precisa ser reiniciada a cada volta do de fora. O sintoma é a segunda fileira da grade vazia, sem erro nenhum.

Exercício: adivinhe o número

O programa sorteia (aqui, fixa) um número secreto e o jogador chuta até acertar. A cada chute errado, o programa diz se o segredo é maior ou menor, e no fim informa quantas tentativas foram necessárias. Reúne a sentinela (o acerto é o fim), um if dentro do laço e um contador.

segredo = 65
palpite = int(input("Palpite: "))
tentativas = 1
while palpite != segredo:
    if palpite < segredo:
        print("maior")
    else:
        print("menor")
    palpite = int(input("Palpite: "))
    tentativas = tentativas + 1
print("acertou em", tentativas, "tentativas")

Com os palpites 50, 75, 62, 68 e 65, a saída alterna maior, menor, maior, menor e termina com acertou em 5 tentativas. O contador começa em 1 porque o primeiro palpite é lido antes do laço, e cada leitura dentro do laço soma mais uma tentativa. Para ampliar, acrescente um limite de tentativas na condição, while palpite != segredo and tentativas < 7, e uma mensagem de derrota depois do laço, como no exemplo da senha.

Perguntas frequentes

Qual a diferença entre while e if?

O if testa uma vez e segue em frente. O while volta ao teste depois de cada execução do bloco e só segue quando ele falha.

Quando usar while e quando usar for?

Use for quando já se sabe o que percorrer (os números de 1 a 10, os itens de um grupo). Use while quando o fim depende de algo que só aparece rodando, como uma resposta do usuário, uma leitura de sensor ou uma condição que muda sozinha.

O que é while True?

É um laço cuja condição nunca fica falsa. Ele termina por um break dentro do corpo ou quando o programa é interrompido. É a estrutura do laço principal da ESP32, e o artigo sobre break e continue mostra os outros usos.

O while pode ter else?

Pode, e o bloco do else roda quando o teste falha, mas não quando o laço é interrompido por break. O assunto é do artigo sobre break, continue e o else dos laços.

Como descubro por que o meu laço não termina?

Coloque um print com a variável do teste dentro do laço e acompanhe os valores, como na tabela de acompanhamento do artigo anterior. Se o valor não muda, falta a atualização. Se muda mas nunca chega ao limite, o sentido está errado ou a condição está mal escrita.

Para continuar

A trilha Lógica com Python tem os desafios de repetição. O Até zero é a sentinela mais simples, a Soma dinâmica soma valores com a sentinela, a Senha 1234 repete a leitura até acertar, e a Média de N combina contador e acumulador. Para a base, releia Por que repetir.

O próximo assunto é o laço for e a função range(): a forma curta de repetir um número conhecido de vezes, sem escrever as quatro peças à mão.

Para praticar no PyPlaca

Trilhas

Lições

Fichas de componentes

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

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