Python: Lógica Booleana
Na Lição 03, aprendemos sobre operadores, incluindo os operadores lógicos
and,or,not. Nesta lição, vamos focar em julgamentos de verdadeiro/falso — o conceito mais fundamental da ciência da computação. A lógica booleana é a base de todas as declarações condicionais, controles de loop e verificações de permissão.
1. Valores Booleanos: True e False
Existem apenas dois valores booleanos: True e False. Eles recebem o nome do matemático britânico George Boole, que fundou a álgebra booleana — a base teórica do "0 e 1" da computação moderna.
print(True) # Saída: True
print(False) # Saída: False
print(type(True)) # <class 'bool'>
Operadores de comparação produzem resultados booleanos:
print(5 > 3) # True
print(10 == 5) # False
print(7 <= 7) # True
print(3 != 3) # False
(1) Booleanos também são números
Em Python, True e False são, na verdade, subclasses de int — True é equivalente a 1, False a 0:
print(True + True) # 2 (True=1, dois True = 2)
print(True * 10) # 10
print(False * 100) # 0
Aviso: Embora
True == 1eFalse == 0sejam válidos em Python (entãoTrue + Trueé igual a 2), nunca use-os dessa forma. Valores booleanos servem para julgamento lógico, não para aritmética. Escrever código comoscore + Truedeixará os leitores confusos.
▶ Exemplo: Resultados da Verificação de Saúde (Dificuldade ⭐)
# Gera valores booleanos com operadores de comparação
age = 25
height = 175
weight = 70
is_adult = age >= 18 # True
is_tall = height > 170 # True
is_heavy = weight > 80 # False
print(f"Adult: {is_adult}")
print(f"Tall: {is_tall}")
print(f"Overweight: {is_heavy}")
# Imprime valores booleanos diretamente — eles são valores, não texto
print(f"Adult AND Tall: {is_adult and is_tall}")
Output:
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True
2. not: Negação
not significa "inverter" — preto vira branco, branco vira preto.
print(not True) # False
print(not False) # True
print(not (5 > 3)) # False (5>3 é True, negado vira False)
not é comumente usado em dois cenários:
Cenário 1: Verificando "não atender a uma condição"
# Não é admin — não pode entrar no backend
is_admin = False
if not is_admin:
print("You do not have admin access.")
# Saída: You do not have admin access.
Cenário 2: Verificando se uma variável está vazia
# Verifica se o usuário não forneceu um nome
username = ""
if not username:
print("Username cannot be empty!")
# Saída: Username cannot be empty!
Aqui há um truque de "conversão booleana implícita" do Python — a string vazia "" é equivalente a False em verificações de condição. Portanto, not username é True quando username é uma string vazia. Veremos quais valores são "falsy" mais adiante.
Dica:
notsignifica "negação." No código,if not is_admin:se lê como "se não for admin."
3. and: Ambos devem ser True
and significa "ambos" — ambas as condições devem ser verdadeiras para que o resultado seja True. Se qualquer uma for falsa, o resultado é False.
| Esquerda | Direita | Resultado |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
age = 22
has_id = True
# Ambas as condições devem ser atendidas
can_buy_alcohol = age >= 18 and has_id
print(can_buy_alcohol) # True (tem idade e tem documento)
# Outro cenário: solicitar cartão de crédito exige renda >= 50 mil E score de crédito >= 600
income = 80 # milhares
credit_score = 650
qualified = income >= 50 and credit_score >= 600
print(f"Credit card application: {qualified}") # True
▶ Exemplo: Verificação de Login (Dificuldade ⭐)
# Simula login — nome de usuário correto E senha correta
username_correct = True
password_correct = False
can_login = username_correct and password_correct
print(f"Login result: {can_login}") # False — senha errada
# Adiciona outra camada: a conta não deve estar bloqueada
account_locked = True
can_login = username_correct and password_correct and not account_locked
print(f"Final result: {can_login}") # False — a conta está bloqueada
Output:
Login result: False
Final result: False
4. or: Pelo menos um True
or significa "qualquer um" — se pelo menos uma condição for verdadeira, o resultado é True. Somente quando ambas são falsas o resultado é False.
| Esquerda | Direita | Resultado |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
# Pode descansar nos fins de semana ou feriados
is_weekend = True
is_holiday = False
can_rest = is_weekend or is_holiday
print(can_rest) # True (é fim de semana)
# Segurança do metrô: se você tem água OU uma bebida, precisa de verificação
has_water = True
has_drink = False
need_check = has_water or has_drink
print(f"Security check needed: {need_check}") # True
(1) Exercício: Verificação completa da tabela-verdade
# Verifica a tabela-verdade com código — todas as combinações de and e or
a = True
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = True
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
Output:
True and True = True
True or True = True
True and False = False
True or False = True
False and True = False
False or True = True
False and False = False
False or False = False
5. Avaliação de Curto-Circuito
Mencionamos isso na Lição 03, mas é tão importante que vamos nos aprofundar. Os operadores lógicos do Python param de avaliar imediatamente assim que o resultado é determinado, sem executar a expressão restante.
(1) Curto-circuito do and: Esquerda é False -> Direita não é executada
def check_right():
print("-> check_right was called!")
return True
print("False and check_right():")
result = False and check_right() # check_right NÃO será executada
print(f"Result: {result}\n")
print("True and check_right():")
result = True and check_right() # check_right será executada
print(f"Result: {result}")
Output:
False and check_right():
Result: False
True and check_right():
-> check_right was called!
Result: True
(2) Curto-circuito do or: Esquerda é True -> Direita não é executada
print("True or check_right():")
result = True or check_right() # check_right NÃO será executada
print(f"Result: {result}")
(3) Usos clássicos da avaliação de curto-circuito
1. Acesso seguro: prevenindo erros de None
# Suponha que user possa ser None (o usuário não existe)
user = None
# user.get("name") daria erro — None não tem o método get
# Use curto-circuito para proteger:
name = user and user.get("name")
print(name) # None — user é falsy, ocorreu curto-circuito, user.get() não foi chamado
# Se o usuário existir:
user = {"name": "Xiao Ming"}
name = user and user.get("name")
print(name) # Xiao Ming
2. Definindo valores padrão
# Se o usuário não digitou um nome, use um padrão
user_input = "" # String vazia (falsy)
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, guest
user_input = "Zhang San"
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, Zhang San
Dica: O padrão
user_input or "default"é muito "pythonico" — se o lado esquerdo for falsy (string vazia), use o direito; se for truthy (tem conteúdo), use o esquerdo. Ele aproveita o comportamento de curto-circuito door.
6. Valores Truthy e Falsy
Em Python, qualquer valor pode ser usado como booleano em uma condição. Alguns valores são considerados "falsy", e todo o resto é "truthy".
(1) Valores falsy comuns
# Esses valores são equivalentes a False em condições
print(bool(False)) # False — booleano falso
print(bool(0)) # False — zero
print(bool(0.0)) # False — zero de ponto flutuante
print(bool("")) # False — string vazia
print(bool([])) # False — lista vazia (abordada mais adiante)
print(bool(None)) # False — valor nulo
Todo o resto é truthy:
print(bool(1)) # True — número diferente de zero
print(bool(-5)) # True — números negativos também são truthy!
print(bool("Python")) # True — string não vazia
print(bool(" ")) # True — um espaço é um caractere, não vazio é truthy
print(bool([1, 2])) # True — lista não vazia
Aviso:
-5e" "(espaço) são ambos truthy, o que pode surpreender você.-5é um inteiro diferente de zero, então é truthy. Um espaço é um caractere, tornando a string não vazia, então é truthy. Apenas a string vazia""é falsy.
(2) Usando truthiness para simplificar o código
# Não recomendado (verboso)
name = "Xiao Ming"
if name != "":
print(f"Hello, {name}")
# Recomendado (conciso)
name = "Xiao Ming"
if name:
print(f"Hello, {name}")
# Não recomendado
score = 85
if score != 0:
print(f"Score: {score}")
# Recomendado
score = 85
if score:
print(f"Score: {score}")
Dica: Aproveitar a truthiness deixa o código mais limpo.
if name:é mais "pythonico" do queif name != "":. Mas cuidado para não exagerar —if score:não será executado quandoscore=0. Se você precisa distinguir entre "score é 0" e "sem score", useis not None.
7. is e is not: Comparação de identidade
is compara se duas variáveis apontam para o mesmo objeto (o mesmo espaço na memória), não se seus valores são iguais. Mencionamos isso na Lição 03; aqui estão mais exemplos para reforçar.
# == compara valores, is compara identidade
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — mesmos valores
print(a is b) # False — mas não é o mesmo objeto de lista
print(a is c) # True — c é a, aponta para a mesma lista
# Cache de inteiros pequenos (otimização interna do Python)
x = 256
y = 256
print(x is y) # Pode ser True — inteiros pequenos são armazenados em cache
x = 1000
y = 1000
print(x is y) # Pode ser False — inteiros grandes não são armazenados em cache
Aviso: Nunca use
ispara comparar inteiros ou strings por valor. Embora inteiros pequenos às vezes possam retornarTruecomisdevido à otimização interna do Python, isso é um detalhe de implementação e não é confiável. Sempre use==para comparação de valores.
(1) O uso correto: verificando None
A comunidade Python tem uma convenção — ao verificar se um valor é None, sempre use is, nunca ==:
# Abordagem correta
result = None
if result is None:
print("No result")
# Não recomendado
if result == None:
print("No result")
▶ Exemplo: Validação de Condições de Cadastro (Dificuldade ⭐⭐)
username = "alice2026"
password = "abc123"
age = 20
agreed_terms = True
is_valid = (
bool(username) and
len(password) >= 6 and
age >= 18 and
agreed_terms
)
reason = (
(not username and "Username is empty") or
(len(password) < 6 and "Password too short") or
(age < 18 and "Underage") or
(not agreed_terms and "Terms not agreed") or
"Registration successful"
)
print(f"Registration result: {is_valid}")
print(f"Reason: {reason}")
age = 16
is_valid2 = bool(username) and len(password) >= 6 and age >= 18 and agreed_terms
reason2 = (
(not username and "Username is empty") or
(len(password) < 6 and "Password too short") or
(age < 18 and "Underage") or
(not agreed_terms and "Terms not agreed") or
"Registration successful"
)
print(f"Registration result: {is_valid2}")
print(f"Reason: {reason2}")
Output:
Registration result: True
Reason: Registration successful
Registration result: False
Reason: Underage
8. Casos de uso comuns
- Controle de permissão:
is_admin or (is_logged_in and has_permission)— combine várias condições para decidir o que um usuário pode fazer. - Validação de entrada:
username and password— verifique se o usuário forneceu ambos. - Padrões de parâmetros opcionais:
timeout or 30— se o timeout não estiver definido, use o padrão de 30 segundos. - Cadeia de acesso seguro:
user and user.address and user.address.city— acesso seguro camada por camada; curto-circuito em qualquer etapa falsy. - Controle de alternância:
is_enabled and is_connected— ambas as condições devem ser atendidas para a operação prosseguir.
❓ Perguntas Frequentes
P: Qual é a diferença entre
Truee"True"? R:True(sem aspas) é um valor booleano;"True"(com aspas) é uma string. Eles são diferentes:type(True)é<class 'bool'>,type("True")é<class 'str'>. Em uma condição,if "True":é sempre True (string não vazia é truthy), eif "False":também é sempre True (também não vazio). Portanto, nunca coloque aspas em valores booleanos em condições.
P: Quando devo usar
isem vez de==? R: Use==em 99% dos casos.isé convencional apenas em um cenário — verificarNone:if result is None:. Use==para todas as outras comparações de valor. Lembre-se:==compara "valor",iscompara "identidade".
P: Quais armadilhas a avaliação de curto-circuito de
and/ortem? R: A armadilha mais comum envolve chamadas de função. Se você colocar uma chamada de função no lado direito deandouor, ela pode não ser executada devido ao curto-circuito, e você não saberá que foi ignorada. Se essa função tiver efeitos colaterais (registrar logs, enviar e-mails, atualizar contadores), o curto-circuito pode causar comportamento inconsistente. Boa prática: se a expressão do lado direito tiver efeitos colaterais, não dependa do curto-circuito — escreva-as separadamente.
P: Por que
not not "hello"retorna True? R:not "hello"primeiro avalia"hello"como booleano (string não vazia é truthy), e nega para obterFalse. Depoisnot not "hello"negaFalsenovamente, obtendoTrue. Entãonot not xé equivalente abool(x)— converter x para booleano. Mas esse padrão é incomum; usebool(x)diretamente para clareza.
📖 Resumo
- Booleanos têm apenas dois valores:
TrueeFalse; eles são subclasses deint(True=1,False=0), mas não os use para aritmética notnega: verdadeiro vira falso, falso vira verdadeiroandexige que ambos sejam verdadeirosorexige que pelo menos um seja verdadeiro- Os valores falsy do Python incluem:
False,0,0.0,"",[],None— todo o resto é truthy - Curto-circuito:
andcom a esquerda falsa -> direita não executada;orcom a esquerda verdadeira -> direita não executada - O curto-circuito permite dois padrões clássicos: "acesso seguro" e "valores padrão"
iscompara identidade,==compara valor; useispara verificações deNone
📝 Exercícios
-
Iniciante (Dificuldade ⭐): Preveja os valores dessas expressões e depois verifique:
not (10 > 5)True and False or Truenot False and True(5 > 3) or (2 > 10) and (8 == 8)— Dica: Atenção à precedência —andé maior queor
-
Intermediário (Dificuldade ⭐⭐): Escreva código para validar a string de entrada de um usuário:
- Se a entrada estiver vazia, imprima "Input cannot be empty"
- Se a entrada for só espaços, trate também como "Input cannot be empty" (Dica: use
strip()) - Se o comprimento da entrada for menor que 6, imprima "Input must be at least 6 characters"
- Caso contrário, imprima "Input is valid"
-
Avançado (Dificuldade ⭐⭐⭐): Escreva um "verificador de número de três dígitos". Dado um número de 3 dígitos
num(ex.: 153), determine:- Ele é par? (use
%) - Ele é divisível por 3 e por 5?
- Ele é um palíndromo? (o dígito das centenas é igual ao das unidades, ex.: 121, 353)
- Quantas das condições acima são atendidas? Imprima a contagem.
Use apenas expressões booleanas para todas as verificações — sem declarações if (guarde isso para a próxima lição).
- Ele é par? (use