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:
a | b | a and b | a or b | not a |
|---|---|---|---|---|
True | True | True | True | False |
True | False | False | True | False |
False | True | False | True | True |
False | False | False | False | True |
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:
FalseeNone- 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 yretornaxsexfor truthy, senão retornay.x and yretornaxsexfor falsy, senão retornay.
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:
andpara no primeiro valor falsy, porque nada depois dele pode tornar a expressão inteira verdadeira.orpara 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/ortestam 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. ComTrueeFalse, 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?
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 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).