Pular para o conteúdo

Fundamentos

A estrutura if e else em Python: decisões, recuo e erros de indentação

Aprenda a usar if e else em Python para o programa escolher entre dois caminhos, entender o recuo como parte da sintaxe e corrigir os erros de indentação.

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

O if faz o programa executar um bloco de código só quando uma condição é verdadeira, e o else define o que fazer quando ela é falsa. O bloco é o conjunto de linhas recuadas logo depois da linha que termina em dois-pontos. Em Python, esse recuo não é enfeite de formatação: ele faz parte da sintaxe, e é ele que diz quais linhas pertencem ao if, quais pertencem ao else e quais já estão fora dos dois.

Até aqui, os programas desta série rodaram de cima para baixo, uma linha depois da outra, sem escolher nada. Com if e else o programa passa a decidir, e todo o trabalho de condições dos dois artigos anteriores ganha um lugar para entrar. Este texto mostra a estrutura, o que pode ir no lugar da condição, as formas curtas, o que muda na ESP32 e os erros de indentação que aparecem em qualquer turma, inclusive com a briga mais antiga da programação: tabs ou espaços.

O problema: o programa que sempre faz a mesma coisa

Imagine um termostato que lê a temperatura de uma sala. Se um programa só soubesse seguir em linha reta, ele ligaria o ventilador sempre ou nunca ligaria, e a leitura do sensor não serviria para nada. O que se quer é o contrário: com 31 graus, ligar o ventilador, e com 22, deixar desligado. Isso é uma decisão, e uma decisão precisa de três coisas: uma pergunta de sim ou não, o que fazer se a resposta for sim e o que fazer se for não.

A pergunta é a condição, a expressão que vira True ou False, como as dos artigos sobre operadores relacionais e lógicos e sobre tabelas-verdade. As duas respostas são os blocos. A estrutura que junta tudo se escreve assim:

temperatura = 31
if temperatura > 30:
    print("ligar ventilador")
else:
    print("ventilador desligado")
print("fim da checagem")
temperatura = 22
if temperatura > 30:
    print("ligar ventilador")
else:
    print("ventilador desligado")
print("fim da checagem")

A saída é ligar ventilador, fim da checagem, ventilador desligado e fim da checagem. O mesmo código, com valores diferentes, tomou caminhos diferentes. E a linha print("fim da checagem") rodou nos dois casos, porque ela está na margem, fora dos dois blocos.

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

A anatomia do if

Fluxograma. De temperatura igual a 31, o fluxo chega a um losango com a pergunta temperatura maior que 30. O ramo True, em verde, leva ao bloco do if, print ligar ventilador. O ramo False, em vermelho, leva ao bloco do else, print ventilador desligado. Os dois blocos se juntam de novo e seguem para print fim da checagem, que roda nos dois casos.
O if e o else escolhem um de dois blocos, e os dois caminhos voltam a se juntar na primeira linha sem recuo.

Uma estrutura if tem quatro partes. A palavra if, que abre a decisão. A condição, que pode ser qualquer expressão que dê verdadeiro ou falso. O dois-pontos no fim da linha, que avisa "o bloco começa aqui". E o bloco, as linhas recuadas com a mesma quantidade de espaços. O else é opcional e tem só duas partes: a palavra, com os dois-pontos, e o seu bloco. Ele não leva condição, porque significa "em todos os outros casos". Se o if e o else aparecem juntos, um e só um dos dois blocos roda.

Depois do último bloco, o programa volta para a margem e segue. É a regra que a figura mostra: os dois caminhos se juntam na primeira linha que não está recuada.

O que pode ir no lugar da condição

Qualquer expressão serve, e o Python decide pelo valor de verdade dela. Pode ser uma comparação (nota >= 6), uma combinação com and, or e not (x > 5 and x < 20), uma variável que já guarda um booleano (via_interditada) ou até um valor que não é booleano. Nesse último caso, a regra é a mesma do artigo anterior: o zero, o texto vazio, a lista vazia e o None contam como falsos, e todo o resto conta como verdadeiro.

for v in (0, 1, "", "texto", [], [0], None, "False", " "):
    if v:
        print(repr(v), "verdadeiro")
    else:
        print(repr(v), "falso")

A saída tem nove linhas: 0 falso, 1 verdadeiro, '' falso, 'texto' verdadeiro, [] falso, [0] verdadeiro, None falso, 'False' verdadeiro e ' ' verdadeiro. Repare nas duas últimas. O texto "False" é verdadeiro, porque não está vazio, e um único espaço também. É um jeito prático de testar "o usuário digitou alguma coisa?": if nome: é verdadeiro se houver texto. Mas é também a origem de um erro conhecido, em que alguém lê "False" do teclado e acha que o programa vai entender como falso.

O for que aparece aqui repete o bloco para cada valor da lista, e o módulo de repetição vai explicá-lo com calma. O que importa neste exemplo é o if e o else dentro dele.

As formas curtas

O Python tem três atalhos que aparecem em código real, e vale reconhecê-los.

nota = 7
situacao = "aprovado" if nota >= 6 else "reprovado"
print(situacao)
if nota >= 6: print("passou")
if nota < 6: print("nao passou")
else: print("ok")
if nota > 5:
    pass
else:
    print("nunca")
print(5 == True, 1 == True, bool("False"))

A saída é aprovado, passou, ok e False True True. O primeiro atalho é a expressão condicional, valor1 if condição else valor2, que escolhe um valor em vez de um bloco: é útil para atribuições curtas, mas quanto mais longa a condição, pior fica a leitura. O segundo é o if de uma linha só, com o comando logo depois dos dois-pontos, que só serve quando o corpo é uma instrução simples. O terceiro é o pass, um comando que não faz nada e existe para ocupar um bloco que a sintaxe exige. Na última linha, uma armadilha: 5 == True é False, embora o 5 seja verdadeiro numa decisão. Por isso if x == True: quase sempre está errado, e o certo é escrever apenas if x:.

Ifs dentro de ifs

Um bloco pode conter outro if. O recuo cresce um nível e o Python entende que o if interno só é avaliado se o externo for verdadeiro.

x = 10
if x > 5:
    print("a")
    if x > 8:
        print("b")
    print("c")
print("d")
nome = ""
if not nome:
    print("sem nome")
if x > 5 and x < 20:
    print("faixa")
if 5 < x < 20:
    print("faixa 2")
if x == 10:
    print("dez")
if x != 10:
    print("nao dez")
else:
    print("e dez")

A saída começa com a, b, c e d: o b fica no segundo nível, o c volta ao primeiro nível de recuo e o d sai de tudo. Depois vêm sem nome, faixa, faixa 2, dez e e dez. Os ifs encadeados e a escolha entre mais de duas opções são o assunto do próximo artigo, com o elif. Por enquanto, a regra de ouro é simples: cada nível de recuo abre um bloco novo, e voltar para a margem esquerda fecha tudo.

O recuo decide a quem a linha pertence

O recuo é o que torna o Python tão legível, e também o que faz um erro de uma linha virar um comportamento diferente sem nenhum aviso. A figura mostra duas versões do mesmo texto.

Dois quadros de código com nota igual a 4. No da esquerda, a linha print parabens está recuada dentro do if, e a saída é só reprovado. No da direita, a mesma linha está na margem, depois do else, e a saída é reprovado e parabens, para todo mundo. Uma legenda diz que o recuo define a quem cada linha pertence e que nenhum erro avisa quando ele está no lugar errado.
O mesmo texto com recuo diferente vira dois programas diferentes, e nenhum deles dá mensagem de erro.
nota = 4
if nota >= 6:
    print("aprovado")
    print("parabens!")
else:
    print("reprovado")
print("---")
if nota >= 6:
    print("aprovado")
else:
    print("reprovado")
print("parabens!")

A saída é reprovado, uma linha de separação, reprovado e parabens!. Na primeira versão, o print("parabens!") está dentro do if, e só quem foi aprovado recebe os parabéns. Na segunda, a linha está na margem, depois do else, e todo mundo recebe, inclusive quem repetiu de ano. Nenhuma das duas versões dá erro, e o programa roda normalmente. Quem escreve a segunda versão sem querer só descobre quando alguém reclama da mensagem.

A convenção do Python, definida no guia de estilo PEP 8, é usar quatro espaços por nível. Não é obrigatório que sejam quatro, mas é obrigatório que sejam sempre os mesmos dentro do mesmo bloco. No editor do PyPlaca, a tecla Tab insere quatro espaços, então dá para apertar Tab sem pensar no assunto.

Em sala de aula: erros de indentação

Os erros abaixo se repetem em toda turma que começa a escrever if, e cada um tem uma mensagem própria. Conhecer a mensagem é metade da correção.

Seis cartões com código e a mensagem de erro de cada um. Faltou o dois-pontos no if: SyntaxError, invalid syntax. Corpo sem recuo: SyntaxError, invalid syntax. Recuo a mais numa linha: IndentationError, unexpected indent. Recuo que não bate com nenhum anterior: IndentationError, unindent doesn't match any outer indent level. Um else sem if: SyntaxError, invalid syntax. Um espaço invisível copiado de PDF ou chat: SyntaxError, invalid syntax.
Os seis tropeços mais comuns com o if e a mensagem que o simulador mostra para cada um.

Faltou o dois-pontos

O erro mais frequente de quem está começando e um dos mais frequentes de quem vem de outra linguagem, onde o bloco abre com chaves ou com a palavra then:

x = 5
if x > 3
    print("maior")
Traceback (most recent call last):
  File "main.py", line 2
SyntaxError: invalid syntax

A mensagem do MicroPython é genérica e aponta a linha do if. O Python do computador é mais gentil e diz SyntaxError: expected ':'. Quando aparecer um invalid syntax numa linha que começa com if, else, for ou while, olhe o fim dela antes de qualquer outra coisa.

O corpo sem recuo

x = 5
if x > 3:
print("maior")
Traceback (most recent call last):
  File "main.py", line 3
SyntaxError: invalid syntax

O dois-pontos está certo, mas a linha seguinte ficou na margem, então o if ficou sem corpo. No Python do computador o erro é mais específico: IndentationError: expected an indented block after 'if' statement on line 2. O erro aponta para a linha 3, a que deveria estar recuada.

O recuo a mais

x = 5
if x > 3:
    print("maior")
        print("de novo")
Traceback (most recent call last):
  File "main.py", line 4
IndentationError: unexpected indent

Uma linha que ficou mais para dentro do que a anterior, sem que a anterior terminasse em dois-pontos, é um recuo que o Python não sabe de onde veio. É comum depois de colar um trecho de código no meio de outro, ou de apertar a barra de espaço sem perceber.

O recuo que não bate

x = 5
if x > 3:
        print("a")
    print("b")
Traceback (most recent call last):
  File "main.py", line 4
IndentationError: unindent doesn't match any outer indent level

A primeira linha do bloco tem oito espaços, e a segunda voltou para quatro, um nível que nunca foi aberto. O Python não sabe se a segunda linha está dentro ou fora. O mesmo erro aparece quando o else fica com um recuo diferente do if a que ele pertence. Já um else sem nenhum if antes dele dá só SyntaxError: invalid syntax.

O espaço que ninguém vê

Quem copia código de um PDF, de um slide ou de uma conversa às vezes leva junto um espaço especial, o "espaço que não quebra" (NBSP). Ele parece igual a um espaço comum e não é. O resultado é um SyntaxError: invalid syntax numa linha que parece perfeita aos olhos. No Python do computador, a mensagem é mais clara: SyntaxError: invalid non-printable character U+00A0. Se uma linha está visivelmente certa e o Python insiste que não, apague os espaços do começo dela e digite de novo.

O erro que não dá erro

O caso mais traiçoeiro é o da seção anterior, quando o recuo errado ainda é um programa válido. Não há mensagem para consultar, só o comportamento estranho. A defesa é ler o código olhando a coluna da margem, e não só o texto, e conferir para cada linha de um bloco a pergunta "a quem esta linha pertence?". Um truque de quem ensina: pedir ao aluno que passe o dedo na linha vertical do recuo e diga em voz alta onde o bloco acaba.

Tabs ou espaços: a briga que não acaba

Existe uma discussão que já azedou equipes, revisões de código e até jantares: o recuo se faz com a tecla Tab ou com a barra de espaço? Na série Silicon Valley, da HBO, o tema virou piada com direito a crise de nervos. Na terceira temporada, o protagonista, Richard Hendricks, é do time dos tabs, e ao programar ao lado de uma antiga paixão que usa espaços, ele não aguenta ouvir o barulho da barra de espaço e acaba cancelando o convite que tinha feito. Na cabeça de Richard, o assunto está encerrado: programador usa tabs, e a discussão não tem segundo turno.

O Python, que leva o recuo mais a sério que qualquer outra linguagem, resolveu o impasse do jeito dele: nas duas escolhas o programa funciona, mas misturar as duas num mesmo bloco, de um jeito que deixe o recuo ambíguo, é proibido. No Python 3, o resultado é um TabError, e é o único caso em que a briga acaba em mensagem de erro. A paz, na prática, é simples. Aperte a tecla Tab se quiser, mas peça ao editor que escreva quatro espaços no lugar, como o do PyPlaca já faz. Richard continua feliz com a tecla dele, a colega continua feliz com a barra de espaço, e o Python só exige que ninguém misture.

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 que muda na ESP32

A estrutura e as regras são as mesmas no MicroPython e no Python do computador. Mudam as mensagens de erro, e uma delas muda o comportamento. A tabela resume o que o simulador mostra e o que o Python do computador (3.13) mostra para os mesmos erros:

ErroSimulador (MicroPython)Python no computador
falta o : no ifSyntaxError: invalid syntaxSyntaxError: expected ':'
corpo sem recuoSyntaxError: invalid syntaxIndentationError: expected an indented block after 'if' statement on line 2
recuo a maisIndentationError: unexpected indentIndentationError: unexpected indent
recuo que não bateIndentationError: unindent doesn't match any outer indent levelIndentationError: unindent does not match any outer indentation level
else sem ifSyntaxError: invalid syntaxSyntaxError: invalid syntax
espaço NBSPSyntaxError: invalid syntaxSyntaxError: invalid non-printable character U+00A0
Tab numa linha e oito espaços na seguinteroda sem reclamarTabError: inconsistent use of tabs and spaces in indentation

A última linha é a que importa. No simulador, o recuo é medido em colunas, e um Tab vale oito. Por isso uma linha com um Tab e outra com oito espaços parecem iguais para ele e o programa roda. No Python do computador, a mistura é recusada com TabError. O mesmo arquivo pode funcionar na placa e falhar no computador, ou o contrário, e a saída segura é a de sempre: quatro espaços em tudo, sem tabs no arquivo.

O if na ESP32 costuma decidir a partir de um pino. Num botão com resistor de pull-up, o pino vale 0 quando o botão está apertado, e o programa liga ou apaga um LED:

from machine import Pin
import time

botao = Pin(4, Pin.IN, Pin.PULL_UP)
led = Pin(2, Pin.OUT)

while True:
    if botao.value() == 0:
        led.value(1)
    else:
        led.value(0)
    time.sleep_ms(50)

O while True: repete o bloco para sempre, e dentro dele o if escolhe o que fazer a cada 50 milissegundos. Repare nos níveis de recuo: o while abre o primeiro, o if e o else ficam nele, e os led.value() ficam um nível mais para dentro. O time.sleep_ms(50) está alinhado com o if, então roda a cada volta, qualquer que seja o resultado. O artigo sobre pull-up e pino flutuante explica por que o botão lê zero quando apertado.

Exercício: ano bissexto

Escreva um programa que diga se um ano é bissexto. A regra: é bissexto quem é divisível por 4, exceto os divisíveis por 100, a menos que também sejam divisíveis por 400. Pense primeiro na condição, com and e or, e use o % para testar a divisibilidade. Confira com 2024, 1900, 2000 e 2023.

for ano in (2024, 1900, 2000, 2023, 2100, 1996):
    if ano % 4 == 0 and (ano % 100 != 0 or ano % 400 == 0):
        print(ano, "bissexto")
    else:
        print(ano, "nao bissexto")

A saída é 2024 bissexto, 1900 nao bissexto, 2000 bissexto, 2023 nao bissexto, 2100 nao bissexto e 1996 bissexto. O 1900 é divisível por 4 e por 100, mas não por 400, então fica de fora, e o 2000 passa pela exceção da exceção. Repare nos parênteses: sem eles, o and seria resolvido antes do or e a condição mudaria de significado, como no artigo sobre os operadores lógicos. Para ler o ano do teclado, troque o for por ano = int(input("Ano: ")), como no artigo sobre conversão de tipos. Um bom teste é montar a tabela-verdade da condição e conferir que o programa a segue.

Perguntas frequentes

Preciso sempre do else?

Não. O if sozinho é a forma mais comum: se a condição for verdadeira, o bloco roda, e se não for, o programa simplesmente segue adiante. O else só entra quando existe uma ação para o caso contrário.

Posso usar parênteses na condição?

Pode, e if (x > 3): funciona. Mas eles não são necessários, e a convenção do Python é omiti-los. Os parênteses servem para agrupar partes da condição, como no exemplo do ano bissexto.

Quantos espaços devo usar no recuo?

Quatro, que é a convenção da comunidade. O que o Python exige é que sejam sempre os mesmos no mesmo bloco. Configure o editor para inserir quatro espaços quando você aperta Tab e evite misturar tabs e espaços no mesmo arquivo.

Qual a diferença entre if x: e if x == True:?

O if x: pergunta se o valor de x é verdadeiro no sentido do Python, o que vale para qualquer número diferente de zero e qualquer texto não vazio. O if x == True: pergunta se x é igual ao True, o que é falso para o número 5. Use a primeira forma.

Por que meu if não faz nada, mas também não dá erro?

Costuma ser a condição que nunca é verdadeira, ou uma linha com recuo errado que saiu do bloco. Imprima a condição antes do if para ver o valor e confira, linha a linha, a coluna em que cada comando começa.

Para continuar

A trilha Lógica com Python tem desafios que usam a estrutura. O Maior de idade e o Par ou ímpar são o aquecimento com um if e um else, o Aprovação na escola cobra uma condição composta, e o Positivo ou negativo pede mais de duas respostas, o que prepara o terreno para o próximo artigo.

O próximo assunto é o if, elif e else em Python: como escolher entre três ou mais caminhos sem empilhar ifs, e como as condições aninhadas se comportam quando o recuo cresce.

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