Todo programa que faz algo interessante precisa tomar decisões, e este artigo mostra como o Python decide. Vamos passar pelos operadores relacionais e lógicos, entender o que a linguagem considera verdadeiro ou falso, e chegar às estruturas de controle com if, elif e else escritas do jeito que a comunidade Python espera ler.

O ponto de partida é o booleano. Um valor booleano representa verdadeiro ou falso e, em Python, os dois valores são True e False — sempre com a primeira letra maiúscula, detalhe que pega quem vem de outras linguagens.

aprovado = True
reprovado = False
print(type(aprovado))  # <class 'bool'>

Praticamente qualquer expressão de comparação resulta num booleano, e é daí que nasce toda tomada de decisão em programação. Os operadores relacionais são justamente os que comparam dois valores e devolvem esse resultado:

a = 10
b = 5

print(a == b)   # False — igual a
print(a != b)   # True  — diferente de
print(a > b)    # True  — maior que
print(a < b)    # False — menor que
print(a >= 10)  # True  — maior ou igual a
print(a <= 9)   # False — menor ou igual a

Vale gravar uma distinção que responde por boa parte dos bugs de quem está começando: = é atribuição e == é comparação. São coisas diferentes e o Python não perdoa a troca.

x = 5       # atribuição — x recebe o valor 5
x == 5      # comparação — retorna True

Comparações isoladas raramente bastam; normalmente você precisa combiná-las, e é para isso que servem os operadores lógicos. O and devolve True apenas quando ambas as condições são verdadeiras:

idade = 25
tem_carteira = True

pode_dirigir = idade >= 18 and tem_carteira
print(pode_dirigir)  # True

Sua tabela verdade é curta o suficiente para memorizar:

True  and True  → True
True  and False → False
False and True  → False
False and False → False

Já o or é mais permissivo: basta que pelo menos uma das condições seja verdadeira.

tem_dinheiro = False
tem_cartao = True

pode_pagar = tem_dinheiro or tem_cartao
print(pode_pagar)  # True
True  or True  → True
True  or False → True
False or True  → True
False or False → False

E o not simplesmente inverte o valor booleano:

chovendo = False
print(not chovendo)   # True
print(not True)       # False
print(not False)      # True

Quando os três aparecem na mesma expressão, a precedência é not primeiro, depois and, depois or. Saber a regra de cor é útil, mas escrever confiando nela é pedir problema — use parênteses e deixe a intenção explícita para quem for ler depois:

a = True
b = False
c = True

resultado = a and not b or c
print(resultado)  # True

# Equivalente mais legível com parênteses:
resultado = (a and (not b)) or c
print(resultado)  # True

Aqui entra uma característica do Python que costuma surpreender: qualquer valor pode ser avaliado em contexto booleano, não apenas True e False. Alguns valores são considerados falsy, equivalentes a falso — é o caso de False, do inteiro 0, do float 0.0, da string vazia "", de None, da lista vazia [], do dicionário vazio {} e da tupla vazia (). Todo o resto é truthy.

print(bool(0))      # False
print(bool(1))      # True
print(bool(""))     # False
print(bool("oi"))   # True
print(bool(None))   # False
print(bool([]))     # False
print(bool([1,2]))  # True

Esse comportamento é muito explorado no dia a dia para checar se uma variável tem conteúdo, sem precisar comparar com vazio explicitamente:

nome = ""
if nome:
    print(f"Olá, {nome}")
else:
    print("Nome não informado")
# Saída: Nome não informado

Com os operadores no lugar, chegamos à estrutura que de fato controla o fluxo. O if executa um bloco apenas quando a condição é verdadeira, e não faz nada quando ela é falsa:

temperatura = 35

if temperatura > 30:
    print("Está quente!")

Saída:

Está quente!

Acrescentando o else, você garante um caminho alternativo:

nota = 5.5

if nota >= 6:
    print("Aprovado")
else:
    print("Reprovado")

Saída:

Reprovado

Quando as possibilidades são mais de duas, o elif — abreviação de "else if" — encadeia verificações em sequência. Apenas o primeiro bloco cuja condição for verdadeira é executado, e os demais são ignorados:

nota = 7.5

if nota >= 9:
    print("Excelente")
elif nota >= 7:
    print("Bom")
elif nota >= 5:
    print("Regular")
else:
    print("Insuficiente")

Saída:

Bom

Você pode ter quantos elif quiser, mas apenas um if e um else por bloco.

Também é possível aninhar condicionais, colocando um if dentro do outro:

idade = 20
tem_ingresso = True

if idade >= 18:
    if tem_ingresso:
        print("Pode entrar")
    else:
        print("Precisa comprar ingresso")
else:
    print("Menor de idade, não pode entrar")

Saída:

Pode entrar

Funciona, mas aninhamento profundo torna o código difícil de acompanhar. Em Python, prefira achatar a estrutura combinando condições com and e or — o mesmo exemplo fica assim, bem mais legível:

if idade >= 18 and tem_ingresso:
    print("Pode entrar")
elif idade >= 18:
    print("Precisa comprar ingresso")
else:
    print("Menor de idade, não pode entrar")

Para os casos em que o if/else só escolhe entre dois valores, existe uma forma compacta de escrever tudo numa linha, chamada de expressão ternária ou condicional inline. A sintaxe é valor_se_verdadeiro if condicao else valor_se_falso:

idade = 20
status = "maior" if idade >= 18 else "menor"
print(status)  # maior
nota = 7
resultado = "Aprovado" if nota >= 6 else "Reprovado"
print(resultado)  # Aprovado

numero = -5
absoluto = numero if numero >= 0 else -numero
print(absoluto)  # 5

Reserve o ternário para expressões simples como essas. Assim que a lógica ganha complexidade, o if/elif/else tradicional volta a ser a escolha certa.

Outra conveniência que Python oferece e a maioria das linguagens não é o encadeamento de comparações, escrito exatamente como você faria em notação matemática:

x = 5

# Em outras linguagens você escreveria: x > 0 and x < 10
# Em Python você pode escrever:
print(0 < x < 10)   # True

nota = 7.5
print(6 <= nota <= 10)  # True

idade = 25
print(18 <= idade <= 65)  # True

Além de mais curto, é a forma preferida pelo estilo Python descrito na PEP 8.

Uma função que aparece bastante em código de IA e ML é isinstance(), usada para confirmar o tipo de uma variável antes de operar sobre ela:

x = 3.14

if isinstance(x, float):
    print("É um número decimal")
elif isinstance(x, int):
    print("É um número inteiro")
else:
    print("É outro tipo")

Saída:

É um número decimal

Passando uma tupla de tipos, você verifica vários de uma vez:

valor = 42
if isinstance(valor, (int, float)):
    print("É um número")

Vale fechar com três hábitos que separam código condicional bem escrito de código apenas funcional. O primeiro é não comparar booleanos com True ou False explicitamente — a própria variável já é a condição:

# Ruim
if ativo == True:
    print("Ativo")

# Bom
if ativo:
    print("Ativo")

# Ruim
if ativo == False:
    print("Inativo")

# Bom
if not ativo:
    print("Inativo")

O segundo é não envolver em if aquilo que já é um booleano. Se a função devolve o resultado de uma comparação, devolva a comparação:

# Ruim
def eh_maior(a, b):
    if a > b:
        return True
    else:
        return False

# Bom
def eh_maior(a, b):
    return a > b

E o terceiro é quebrar condições longas em várias linhas com parênteses, para que cada critério fique visível:

# Difícil de ler
if idade >= 18 and tem_documento and not esta_banido and saldo > 0:
    pass

# Mais legível
if (idade >= 18
        and tem_documento
        and not esta_banido
        and saldo > 0):
    pass

Para amarrar tudo, um exemplo prático parecido com o que você encontraria num projeto de saúde ou de ML: um classificador de IMC que lê dados do usuário, calcula o índice e percorre uma cadeia de faixas até encontrar a que se aplica.

peso = float(input("Digite seu peso em kg: "))
altura = float(input("Digite sua altura em metros: "))

imc = peso / (altura ** 2)
print(f"\nSeu IMC é: {imc:.2f}")

if imc < 18.5:
    classificacao = "Abaixo do peso"
    risco = "baixo"
elif imc < 25:
    classificacao = "Peso normal"
    risco = "muito baixo"
elif imc < 30:
    classificacao = "Sobrepeso"
    risco = "aumentado"
elif imc < 35:
    classificacao = "Obesidade grau I"
    risco = "alto"
elif imc < 40:
    classificacao = "Obesidade grau II"
    risco = "muito alto"
else:
    classificacao = "Obesidade grau III"
    risco = "extremamente alto"

print(f"Classificação: {classificacao}")
print(f"Risco de doenças cardiovasculares: {risco}")

Exemplo de saída:

Seu IMC é: 24.22
Classificação: Peso normal
Risco de doenças cardiovasculares: muito baixo

Recapitulando o essencial: operadores relacionais devolvem booleanos, operadores lógicos os combinam, e qualquer valor pode ser lido como verdadeiro ou falso graças às regras de truthy e falsy. O trio if/elif/else controla o fluxo, o ternário resolve condicionais simples numa linha, comparações encadeadas como 0 < x < 10 deixam intervalos legíveis, e isinstance() verifica tipos com segurança.


Os seis exercícios abaixo cobrem exatamente esses pontos, do mais mecânico ao mais conceitual. Tente resolver cada um antes de abrir a resposta comentada.

  1. Escreva um programa que receba a idade de uma pessoa via input() e imprima: - "Criança" se a idade for menor que 12 - "Adolescente" se for entre 12 e 17 - "Adulto" se for entre 18 e 59 - "Idoso" se for 60 ou mais

    ✓ Resposta:
    idade = int(input("Digite sua idade: "))
    
    if idade < 12:
        print("Criança")
    elif idade < 18:
        print("Adolescente")
    elif idade < 60:
        print("Adulto")
    else:
        print("Idoso")
    

    Nota: perceba que não precisamos escrever idade >= 12 and idade < 18 no elif, pois se chegou no elif, já sabemos que idade >= 12 (a condição anterior foi falsa).

  2. Sem rodar o código, diga o que cada print vai exibir e explique o motivo:

    print(bool(0))
    print(bool("False"))
    print(bool([]))
    print(bool(None))
    print(bool(-1))
    print(not not True)
    

    ✓ Resposta:
    bool(0)       → False   — 0 é falsy em Python
    bool("False") → True    — qualquer string não vazia é truthy, mesmo que o conteúdo seja "False"
    bool([])      → False   — lista vazia é falsy
    bool(None)    → False   — None é sempre falsy
    bool(-1)      → True    — qualquer número diferente de zero é truthy, inclusive negativos
    not not True  → True    — not True = False, not False = True, resultado final = True
    
  3. O código abaixo tem um erro lógico (não de sintaxe — ele roda, mas dá resultado errado). Identifique e corrija:

    nota = 8
    
    if nota >= 5:
        print("Regular")
    elif nota >= 7:
        print("Bom")
    elif nota >= 9:
        print("Excelente")
    else:
        print("Insuficiente")
    

    ✓ Resposta:

    O erro lógico está na ordem dos elif. Como nota = 8 satisfaz nota >= 5, o programa entra no primeiro bloco e imprime "Regular", nunca chegando a verificar nota >= 7.

    A ordem correta é sempre da condição mais restritiva para a menos restritiva:

    nota = 8
    
    if nota >= 9:
        print("Excelente")
    elif nota >= 7:
        print("Bom")
    elif nota >= 5:
        print("Regular")
    else:
        print("Insuficiente")
    

    Saída correta:

    Bom
    
  4. Reescreva o trecho abaixo usando o operador ternário em uma única linha:

    numero = -8
    if numero >= 0:
        sinal = "positivo ou zero"
    else:
        sinal = "negativo"
    print(sinal)
    

    ✓ Resposta:
    numero = -8
    sinal = "positivo ou zero" if numero >= 0 else "negativo"
    print(sinal)
    

    Saída:

    negativo
    
  5. Explique a diferença entre os dois códigos abaixo e diga qual é o resultado de cada um:

    # Código A
    x = 5
    if x > 3:
        if x > 7:
            print("maior que 7")
        else:
            print("entre 3 e 7")
    
    # Código B
    x = 5
    if x > 3 and x > 7:
        print("maior que 7")
    else:
        print("entre 3 e 7")
    

    ✓ Resposta:

    Código A imprime "entre 3 e 7" porque o if x > 7 está aninhado dentro do if x > 3. Como x = 5 satisfaz x > 3, entra no bloco externo. Dentro dele, x > 7 é False, então cai no else interno.

    Código B também imprime "entre 3 e 7", mas por outro motivo. A condição x > 3 and x > 7 é equivalente a apenas x > 7 (pois todo número maior que 7 já é maior que 3). Como x = 5 não é maior que 7, a condição é False, e cai no else.

    Neste caso os dois imprimem o mesmo resultado, mas o Código B tem um erro lógico conceitual: o else não está limitado a "entre 3 e 7", mas sim a "não é maior que 7", incluindo números menores ou iguais a 3 também.

  6. Dado o código abaixo, explique o que são valores truthy e falsy e por que o Python se comporta dessa forma ao avaliar condições:

    valores = [0, 1, "", "oi", None, [], [0], False, True]
    for v in valores:
        if v:
            print(f"{repr(v)} → truthy")
        else:
            print(f"{repr(v)} → falsy")
    

    ✓ Resposta:

    O resultado do código seria:

    0     → falsy
    1     → truthy
    ''    → falsy
    'oi'  → truthy
    None  → falsy
    []    → falsy
    [0]   → truthy
    False → falsy
    True  → truthy
    

    Valores truthy e falsy existem porque Python permite usar qualquer expressão como condição em um if, não apenas booleanos literais. O interpretador converte internamente o valor para bool quando necessário.

    A lógica geral é: valores que representam "vazio", "ausência" ou "zero" são falsy. Todo o resto é truthy. Isso permite escrever código mais conciso como if lista: em vez de if len(lista) > 0:, o que é considerado mais Pythonico.

    Repare que [0] é truthy porque a lista não está vazia (ela contém um elemento, mesmo que esse elemento seja 0). O que importa para listas é se estão vazias ou não, não o valor dos elementos.


Para aprofundar: