Python else nos Laços

Na aula break e continue, a busca parava com break quando achava o que procurava. Mas e quando não acha? O laço termina do mesmo jeito, chega na mesma linha, e o programa não tem como saber o que aconteceu. Para isso o Python tem um recurso que muitas outras linguagens não têm: um else ("senão") pendurado no laço. Ele roda quando o laço chega ao fim sem ter passado por um break: o caso de "procurei em tudo e não achei".

Você vai aprender
  • Onde se escreve o else de um for e de um while, e quando ele roda.
  • A regra única: o else roda se o laço terminou sozinho, e não roda se saiu por break.
  • A avisar "não está na lista", "acesso bloqueado" e "acabaram as tentativas".
  • A descobrir se um número é primo com for, break e else.
  • Os casos que surpreendem: laço sem break e lista vazia.
  • Outras formas de fazer (a variável achou e o operador in) e os erros reais de indentação.

Todos os programas desta aula rodaram no Python 3.14 da máquina da Ana (usuária ana, computador notebook), com python3 arquivo.py.


A ideia: "se abrir todas as gavetas e não achar, avise"

A Ana pede ao filho: "Procure a chave nas gavetas. Achou, pode parar. Se abrir todas e não achar, me avise." Repare que esse aviso só faz sentido em um dos finais da busca:

Como a busca terminouNo laçoAvisa "não achei"?
Achou a chave e parou no meioSaiu por breakNão
Abriu todas as gavetas, uma por uma, e a chave não estava em nenhumaO laço terminou sozinhoSim

O else do laço é esse aviso. Ele não quer dizer "senão" no sentido do if e else; é mais um "se não houve break". Muita gente lê o else de um laço como "nobreak" (em inglês, "sem break"), e é um bom jeito de lembrar.


1. for com else: procurar e não achar

A lista de convidados da festa, agora procurando o Fábio, que não foi convidado:

convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Fábio"
for nome in convidados:
    if nome == procurado:
        print(f"{procurado} está na lista.")
        break
else:
    print(f"{procurado} não está na lista.")
print("Fim da busca.")
$ python3 busca_else.py
Fábio não está na lista.
Fim da busca.
for nome in convidados:
Passa pelos cinco nomes.
if nome == procurado: … break
Se achar, avisa e sai do laço com break.
else:
Atenção à indentação: o else está na margem esquerda, alinhado com o for, e não com o if. É isso que faz dele o else do laço. Leva dois-pontos, como o for.
print(f"{procurado} não está na lista.")
O bloco do else, indentado. Roda uma vez, depois da última volta, e só se nenhum break aconteceu.
print("Fim da busca.")
Fora do laço e fora do else: roda sempre.

O Fábio não estava em nenhuma volta, o break nunca rodou, o laço terminou sozinho, e o else deu o aviso. Agora, procurando a Carla (só a segunda linha muda: procurado = "Carla"):

$ python3 busca_else_carla.py
Carla está na lista.
Fim da busca.

Na terceira volta, achou a Carla, e o break saiu do laço pulando o else. O programa foi direto para o Fim da busca..

CaminhoRoda o else?Depois
O laço passou por todos os itens (ou a condição do while ficou falsa)SimPrimeira linha depois do else
O laço saiu por breakNãoPrimeira linha depois do else

Missão: este programa procura o Mateus e não diz nada quando não acha. Acrescente um else ao laço (alinhado com o for) que mostre Mateus não está na lista.

convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Mateus"
for nome in convidados:
    if nome == procurado:
        print(f"{procurado} está na lista.")
        break
print("Fim da busca.")
convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Mateus"
for nome in convidados:
    if nome == procurado:
        print(f"{procurado} está na lista.")
        break
else:
    print(f"{procurado} não está na lista.")
print("Fim da busca.")

2. A senha com três chances, agora completa

Na aula anterior, o programa da senha terminava igual acertando ou errando as três. Com o else, dá para bloquear o acesso só quando as tentativas acabam:

for tentativa in range(1, 4):
    senha = input(f"Senha (tentativa {tentativa} de 3): ")
    if senha == "pao123":
        print("Bem-vinda, Ana!")
        break
    print("Senha errada.")
else:
    print("Três erros: acesso bloqueado.")
print("Fim do programa.")

Errando as três, o range acaba, o laço termina sozinho, e o else roda:

$ python3 senha_else.py
Senha (tentativa 1 de 3): abc
Senha errada.
Senha (tentativa 2 de 3): 123
Senha errada.
Senha (tentativa 3 de 3): pao
Senha errada.
Três erros: acesso bloqueado.
Fim do programa.

Acertando, o break pula o else:

$ python3 senha_else.py
Senha (tentativa 1 de 3): pao123
Bem-vinda, Ana!
Fim do programa.

3. while com else

O while também aceita else, com a mesma regra: ele roda quando a condição fica falsa (o laço terminou sozinho) e não roda se o laço saiu por break. Um jogo de adivinhar com 3 tentativas:

segredo = 7
tentativas = 3
while tentativas > 0:
    palpite = int(input("Seu palpite (1 a 10): "))
    if palpite == segredo:
        print("Acertou!")
        break
    tentativas -= 1
    print(f"Errou! Tentativas restantes: {tentativas}")
else:
    print(f"Acabaram as tentativas. O número era {segredo}.")
$ python3 adivinhe.py
Seu palpite (1 a 10): 3
Errou! Tentativas restantes: 2
Seu palpite (1 a 10): 9
Errou! Tentativas restantes: 1
Seu palpite (1 a 10): 5
Errou! Tentativas restantes: 0
Acabaram as tentativas. O número era 7.
$ python3 adivinhe.py
Seu palpite (1 a 10): 4
Errou! Tentativas restantes: 2
Seu palpite (1 a 10): 7
Acertou!

Na primeira partida, tentativas chegou a 0, a condição 0 > 0 ficou falsa, e o else revelou o número. Na segunda, o break do acerto pulou o else. (Esse jogo vira um projeto inteiro mais adiante: Jogo de Adivinhação.)


4. Um clássico: o número é primo?

Um número é primo quando só se divide (sem sobrar resto) por 1 e por ele mesmo: 2, 3, 5, 7, 11… Para saber se um número é primo, procure um divisor entre 2 e o número menos 1. Achou um? Não é primo, pode parar (break). Procurou em todos e não achou? É primo (else). É exatamente o formato "procurar e não achar":

numero = int(input("Digite um número maior que 1: "))
for divisor in range(2, numero):
    if numero % divisor == 0:
        print(f"{numero} não é primo: divide por {divisor}.")
        break
else:
    print(f"{numero} é primo.")
$ python3 primo.py
Digite um número maior que 1: 7
7 é primo.
$ python3 primo.py
Digite um número maior que 1: 9
9 não é primo: divide por 3.
$ python3 primo.py
Digite um número maior que 1: 2
2 é primo.
range(2, numero)
Os candidatos a divisor: de 2 até o número menos 1 (o fim não entra; veja range()).
numero % divisor == 0
O % dá o resto da divisão (aula Operadores Aritméticos). Resto zero quer dizer que divide certinho.
break
Um divisor basta para provar que não é primo: para de procurar.
else:
Todos os candidatos falharam: é primo.

Repare no 2: range(2, 2) é vazio, o laço deu zero voltas, nenhum break aconteceu, e o else disse "primo", o que está certo. Com o 1 acontece a mesma coisa (range(2, 1) também é vazio), e o programa responde 1 é primo., o que está errado: o 1 não é primo. É por isso que a pergunta pede "um número maior que 1". A seção seguinte fala mais desse caso das zero voltas.


5. Dois casos que surpreendem

Sem break no laço, o else roda sempre

for numero in range(1, 4):
    print(numero)
else:
    print("O else rodou.")
$ python3 sem_break_else.py
1
2
3
O else rodou.

Sem nenhum break, o laço sempre termina sozinho, então o else sempre roda. Funciona, mas não serve para nada: daria no mesmo escrever o print depois do laço, sem else. Use o else de laço só quando houver um break lá dentro.

Lista vazia: o else roda

convidados = []
procurado = "Carla"
for nome in convidados:
    if nome == procurado:
        print(f"{procurado} está na lista.")
        break
else:
    print(f"{procurado} não está na lista.")
$ python3 vazia_else.py
Carla não está na lista.

Zero voltas também é "terminar sem break". Na busca, é o resultado certo: numa lista vazia, ninguém está na lista.


Formas diferentes de fazer a mesma coisa

O "procurar e não achar" tem três jeitos de escrever. O primeiro você já viu: for com break e else.

Com uma variável "achou" (a bandeira)

Antes do laço, uma variável booleana começa em False; quando acha, vira True. Depois do laço, um if comum olha para ela:

convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Fábio"
achou = False
for nome in convidados:
    if nome == procurado:
        achou = True
        break
if achou:
    print(f"{procurado} está na lista.")
else:
    print(f"{procurado} não está na lista.")
$ python3 bandeira.py
Fábio não está na lista.

É o jeito que funciona em qualquer linguagem, e a variável achou continua disponível para usar mais adiante no programa. Custa duas linhas a mais.

Com o operador in

Quando a pergunta é só "este item está na lista?", o Python já tem uma resposta pronta, o in (aula is e in):

convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Fábio"
if procurado in convidados:
    print(f"{procurado} está na lista.")
else:
    print(f"{procurado} não está na lista.")
$ python3 com_in.py
Fábio não está na lista.

Por dentro, o in faz a mesma busca, item por item. O for…else é para quando o teste é mais que uma igualdade: um divisor (o primo), um preço acima de um valor, uma senha numa das tentativas.

SituaçãoQual usar
Só saber se um valor está na listaif valor in lista:
Procurar com um teste próprio e agir quando não acharfor … break … else:
Precisar do resultado da busca mais adiante no programaA variável achou = False / True
Tentativas limitadas (senha, palpites) com aviso no fimfor com range ou while, com break e else:
Um comentário ajuda quem lê

Como o else de laço é pouco conhecido, muita gente o acompanha de um comentário: else: # não achou ou else: # sem break. Assim, quem lê o código não confunde com o else de um if.


Quando dá errado

O else ficou alinhado com o if, e não com o for
convidados = ["Ana", "Bruno", "Carla", "Davi", "Elisa"]
procurado = "Carla"
for nome in convidados:
    if nome == procurado:
        print(f"{procurado} está na lista.")
        break
    else:
        print(f"{procurado} não está na lista.")
$ python3 else_errado.py
Carla não está na lista.
Carla não está na lista.
Carla está na lista.

Nenhum erro, mas uma saída absurda: "não está", "não está", "está". Com 4 espaços, esse else pertence ao if, e roda em cada volta em que o nome não é a Carla (Ana e Bruno). É o erro mais comum com else de laço. Como consertar: tire a indentação do else para alinhá-lo com o for, e o seu bloco com 4 espaços.

Uma linha entre o laço e o else
for numero in range(3):
    print(numero)
print("Contei.")
else:
    print("Fim")
$ python3 else_sozinho.py
  File "/home/ana/else_sozinho.py", line 4
    else:
    ^^^^
SyntaxError: invalid syntax

"Erro de sintaxe: sintaxe inválida", apontando o else da linha 4. O else tem de vir logo depois do bloco do laço. O print("Contei.") na margem esquerda encerrou o for, e um else solto, sem for, while ou if antes dele, não faz sentido. Como consertar: ponha o else imediatamente depois do bloco do laço, e o print("Contei.") depois do else.

Esqueceu os dois-pontos
for numero in range(3):
    print(numero)
else
    print("Fim")
$ python3 else_sem_dp.py
  File "/home/ana/else_sem_dp.py", line 3
    else
        ^
SyntaxError: expected ':'

O else do laço leva dois-pontos, como qualquer linha que abre um bloco. Como consertar: else:.


Referência rápida

EscritaO que faz
for item in lista: … else:O bloco do else roda se o for passou por todos os itens sem break
while condição: … else:O bloco do else roda se a condição ficou falsa sem break
break dentro do laçoSai do laço e pula o else
Laço de zero voltasO else roda (não houve break)
Laço sem nenhum breakO else roda sempre (então não precisa dele)
else: # não achouCostume: um comentário para lembrar que é o else do laço
SintomaCausa provável
"Não achei" aparece várias vezes, antes de acharO else está indentado junto do if, e não alinhado com o for
SyntaxError: invalid syntax apontando o elseHá uma linha entre o fim do laço e o else
SyntaxError: expected ':'Faltaram os dois-pontos do else
O else roda sempreO laço não tem break (ou o break nunca é alcançado)

Exercícios

1. Complete

Complete com a palavra que pula o else do laço quando o 4 aparece:

for n in [1, 3, 4, 7]:
    if n % 2 == 0:
        print("Achei um par")
        
else:
    print("Nenhum par")

2. Quando o bloco else de um for roda?

3. O que este programa mostra? for n in [1, 3, 5]: /     if n % 2 == 0: /         break / else: /     print("Nenhum par")

4. Um for sobre uma lista vazia tem um else. O else roda?

5. Para saber só se "Carla" está na lista convidados, qual é o jeito mais simples?

Missão final: o detector de primos

Missão: o programa já descobre quando um número não é primo, mas fica calado quando ele é. A caixa vai "digitar" 97. Acrescente o else do laço para mostrar 97 é primo. Depois, troque a entrada por 91 e veja o que acontece.

numero = int(input("Digite um número maior que 1: "))
for divisor in range(2, numero):
    if numero % divisor == 0:
        print(f"{numero} não é primo: divide por {divisor}.")
        break
numero = int(input("Digite um número maior que 1: "))
for divisor in range(2, numero):
    if numero % divisor == 0:
        print(f"{numero} não é primo: divide por {divisor}.")
        break
else:
    print(f"{numero} é primo.")

No lab, o 97 deu 97 é primo.. E o 91? Parece primo, mas não é: experimente.


Resumo

  • for e while aceitam um else:, escrito logo depois do bloco do laço e alinhado com o for/while.
  • O else do laço roda quando o laço termina sozinho (acabaram os itens, ou a condição ficou falsa) e é pulado quando o laço sai por break. Pense nele como "nobreak".
  • É o jeito natural de escrever "procurei e não achei": convidado fora da lista, acesso bloqueado, número primo.
  • Zero voltas também roda o else. Sem break no laço, o else não tem utilidade.
  • Alternativas: a variável achou (funciona em qualquer linguagem) e o in (para "está na lista?").
  • Cuidado com a indentação: um else alinhado com o if vira o else do if e roda a cada volta.