Menu

and, or, not em Python: operadores lógicos, curto-circuito e truthiness

Como funcionam os operadores and, or e not do Python: tabelas verdade, valores truthy e falsy, avaliação em curto-circuito, por que and/or retornam um dos operandos, precedência, e and/or contra & e |.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Três palavras em vez de símbolos

Os operadores lógicos do Python são as palavras em inglês and, or e not. Outras linguagens escrevem &&, || e !. Em Python, && e || dão SyntaxError, e ! só aparece como parte de != ("diferente").

Com True e False, as regras são as que você espera:

aba and ba or bnot a
TrueTrueTrueTrueFalse
TrueFalseFalseTrueFalse
FalseTrueFalseTrueTrue
FalseFalseFalseFalseTrue

and precisa que os dois lados sejam verdadeiros. or precisa de pelo menos um. not recebe um único valor e o inverte.

Em código real, os lados costumam ser comparações, e o resultado alimenta um if ou um while:

Saída:

eligible
standard ticket

Isso basta para a maioria das condições. O resto desta página cobre o que os operadores fazem com valores que não são True nem False, e as regras que decidem qual lado de uma expressão é executado.

Valores truthy e falsy

and, or e not aceitam qualquer valor, não só booleanos. O Python decide se um valor conta como verdadeiro pela sua truthiness. Estes valores são falsy:

  • False e None
  • zero de qualquer tipo numérico: 0, 0.0
  • containers e strings vazios: "", [], (), {}, set(), range(0)

Todo o resto é truthy, inclusive "0", "False", [0] e -1. Você pode ver como o Python classifica um valor com bool():

Saída:

0 False
1 True
-1 True
'' False
'0' True
[] False
[0] True
None False
0.0 False

A string "0" é truthy porque é uma string não vazia. Essa pega quem lê números da entrada e testa antes de converter. A página de números e booleanos explica a relação entre bool e int.

and e or retornam um operando

É aqui que o Python difere da maioria das linguagens. and e or não produzem um True ou False novo. Eles retornam um dos dois valores que você passou:

  • x or y retorna x se x for truthy, senão retorna y.
  • x and y retorna x se x for falsy, senão retorna y.

Quando os dois operandos são booleanos, "retornar um operando" e "retornar um booleano" dão no mesmo, e é por isso que a diferença passa despercebida até você misturar outros tipos.

not é a exceção: sempre retorna True ou False.

Se você precisa de um booleano de verdade a partir de uma expressão com and/or, por exemplo para guardar ou retornar de uma função que promete bool, envolva em bool():

Avaliação em curto-circuito

O Python avalia and e or da esquerda para a direita e para assim que a resposta é conhecida:

  • and para no primeiro valor falsy, porque nada depois dele pode tornar a expressão inteira verdadeira.
  • or para no primeiro valor truthy, porque nada depois dele pode tornar a expressão inteira falsa.

O lado pulado não é executado. Dá para ver isso acontecendo com funções que imprimem quando são chamadas:

Saída:

and:
  checking A
False
or:
  checking A
True

B nunca é verificado em nenhum dos casos. O curto-circuito é o que torna as condições de guarda seguras. A segunda metade de cada condição abaixo quebraria sozinha, mas só roda depois que a primeira metade descartou o caso problemático:

Coloque o teste barato ou protetor primeiro. Invertendo a ordem, user.startswith("admin") and user is not None lança AttributeError quando user é None.

Padrões construídos com or e and

Como or retorna o primeiro operando truthy, ele dá um valor padrão em uma linha:

Saída:

Hello, Ada!
Hello, guest!
Hello, guest!

O problema é que or substitui todo valor falsy, não só None. Se 0, "" ou [] for uma entrada legítima, o or vai jogá-la fora:

Use x if x is not None else default quando zero ou vazio for um valor válido. A página de if/else cobre essa expressão condicional.

and tem um padrão equivalente: "use este valor só se o primeiro estiver definido". É menos comum e muitas vezes fica mais claro como if, então use com moderação:

Precedência: not, depois and, depois or

Quando uma expressão mistura os três, o Python aplica not primeiro, depois and, depois or. Comparações como ==, < e in são aplicadas antes de todos eles.

a or b and c e (a or b) and c dão respostas diferentes com os mesmos valores, então uma condição mista deve levar parênteses mesmo quando a ordem padrão por acaso está certa. Eles não custam nada e tiram a dúvida de quem ler depois.

and/or contra &/|

& e | parecem com and e or e às vezes dão a mesma resposta, mas são operadores diferentes.

  • and / or testam truthiness, fazem curto-circuito e retornam um dos operandos.
  • & / | são operadores bitwise. Em inteiros, combinam os bits dos dois números. Em sets, significam interseção e união. Com True e False, retornam um booleano. Nunca fazem curto-circuito: os dois lados são sempre avaliados.

Os operadores bitwise também têm precedência maior que as comparações, o que transforma uma condição escrita com & em outra coisa completamente diferente:

1 & y é 1 & 5, que dá 1, então a linha do meio vira a cadeia 5 > 1 > 1, e 1 > 1 é falso. Em código Python comum, use and, or e not nas condições.

O único lugar onde &, | e ~ são corretos em condições é NumPy e pandas. Um array guarda muitos valores, então não tem um valor de verdade único, e and lança ValueError: The truth value of an array ... is ambiguous. As bibliotecas sobrecarregam & e | para funcionar elemento a elemento, e é por isso que filtros do pandas ficam assim: df[(df.age > 18) & (df.country == "CA")], com parênteses em volta de cada comparação pelo motivo de precedência acima.

any() e all(): and e or sobre uma lista

Para combinar uma sequência inteira de condições, use as funções embutidas all() (um and sobre todos os itens) e any() (um or sobre todos os itens). As duas fazem curto-circuito do mesmo jeito:

Diferente de and e or, any() e all() sempre retornam um booleano.

Erros comuns

Comparar uma variável com vários valores usando or. Esta condição é sempre verdadeira:

O Python lê a primeira condição como (color == "red") or "blue". A comparação é False, então o or retorna "blue", uma string não vazia, que é truthy. Repita a comparação dos dois lados ou, melhor ainda, teste a pertinência com in.

Escrever && ou ||. Os dois dão SyntaxError. Use and e or.

Esperar um booleano de and/or. x = a or b guarda o próprio a ou b. Muitas vezes é isso que você quer, mas se uma função deve retornar True ou False, converta com bool().

Confiar na precedência em condições mistas. a or b and c é válido e bem definido, mas coloque parênteses para ninguém precisar lembrar da regra.

Perguntas frequentes

O que o operador and faz em Python?

a and b é verdadeiro só quando os dois lados são verdadeiros. O Python avalia a primeiro; se a for falsy, retorna a sem olhar para b, senão retorna b. Com booleanos simples isso dá o resultado de sempre: True and False é False.

Por que 0 or 5 retorna 5 em vez de True?

or e and retornam um dos seus operandos, não um booleano novo. x or y retorna x se x for truthy, senão retorna y. 0 é falsy, então 0 or 5 retorna 5. Envolva a expressão em bool() se você precisa de um True ou False de verdade.

Qual a diferença entre and e & em Python?

and é um operador lógico: testa truthiness e faz curto-circuito. & é um operador bitwise: em inteiros combina bits (6 & 3 é 2), em sets calcula a interseção, e sempre avalia os dois lados. Use and em condições de if. A exceção é NumPy e pandas, onde & é o "e" elemento a elemento.

O que roda primeiro em Python, and ou or?

not tem a maior precedência, depois and, depois or. Então a or b and c significa a or (b and c), e not a or b significa (not a) or b. Comparações como == e < têm precedência maior que os três.

Posso usar && e || em Python?

Não. && e || dão SyntaxError em Python. Os operadores lógicos são as palavras and, or e not. Um & ou | sozinho é válido, mas significa outra coisa (and/or bitwise).

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR