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".
- Onde se escreve o
elsede umfore de umwhile, e quando ele roda. - A regra única: o
elseroda se o laço terminou sozinho, e não roda se saiu porbreak. - A avisar "não está na lista", "acesso bloqueado" e "acabaram as tentativas".
- A descobrir se um número é primo com
for,breakeelse. - Os casos que surpreendem: laço sem
breake lista vazia. - Outras formas de fazer (a variável
achoue o operadorin) 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 terminou | No laço | Avisa "não achei"? |
|---|---|---|
| Achou a chave e parou no meio | Saiu por break | Não |
| Abriu todas as gavetas, uma por uma, e a chave não estava em nenhuma | O laço terminou sozinho | Sim |
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
elseestá na margem esquerda, alinhado com ofor, e não com oif. É isso que faz dele oelsedo laço. Leva dois-pontos, como ofor. - print(f"{procurado} não está na lista.")
- O bloco do
else, indentado. Roda uma vez, depois da última volta, e só se nenhumbreakaconteceu. - 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..
| Caminho | Roda o else? | Depois |
|---|---|---|
O laço passou por todos os itens (ou a condição do while ficou falsa) | Sim | Primeira linha depois do else |
O laço saiu por break | Não | Primeira 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ção | Qual usar |
|---|---|
| Só saber se um valor está na lista | if valor in lista: |
| Procurar com um teste próprio e agir quando não achar | for … break … else: |
| Precisar do resultado da busca mais adiante no programa | A variável achou = False / True |
| Tentativas limitadas (senha, palpites) com aviso no fim | for com range ou while, com break e else: |
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
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.
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.
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
| Escrita | O 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ço | Sai do laço e pula o else |
| Laço de zero voltas | O else roda (não houve break) |
Laço sem nenhum break | O else roda sempre (então não precisa dele) |
else: # não achou | Costume: um comentário para lembrar que é o else do laço |
| Sintoma | Causa provável |
|---|---|
| "Não achei" aparece várias vezes, antes de achar | O else está indentado junto do if, e não alinhado com o for |
SyntaxError: invalid syntax apontando o else | Há uma linha entre o fim do laço e o else |
SyntaxError: expected ':' | Faltaram os dois-pontos do else |
O else roda sempre | O 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:
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
forewhileaceitam umelse:, escrito logo depois do bloco do laço e alinhado com ofor/while.- O
elsedo 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 porbreak. 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. Sembreakno laço, oelsenão tem utilidade. - Alternativas: a variável
achou(funciona em qualquer linguagem) e oin(para "está na lista?"). - Cuidado com a indentação: um
elsealinhado com oifvira oelsedoife roda a cada volta.