Tre parole al posto dei simboli
Gli operatori logici di Python sono le parole inglesi and, or e not. Altri linguaggi li scrivono &&, || e !. In Python && e || sono un SyntaxError, e ! compare solo all'interno di != ("diverso da").
Con True e False le regole sono quelle che ti aspetti:
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 richiede che entrambi i lati siano veri. or ne richiede almeno uno. not prende un solo valore e lo inverte.
Nel codice reale i lati sono di solito dei confronti, e il risultato alimenta un if o un while:
Output:
eligible
standard ticket
Questo basta per la maggior parte delle condizioni. Il resto della pagina spiega cosa fanno gli operatori con valori che non sono True o False, e le regole che decidono quale lato di un'espressione viene eseguito.
Valori truthy e falsy
and, or e not accettano qualsiasi valore, non solo i booleani. Python decide se un valore conta come vero in base alla sua truthiness. Questi valori sono falsy:
FalseeNone- lo zero di qualsiasi tipo numerico:
0,0.0 - contenitori e stringhe vuoti:
"",[],(),{},set(),range(0)
Tutto il resto è truthy, compresi "0", "False", [0] e -1. Puoi vedere come Python classifica un valore con bool():
Output:
0 False
1 True
-1 True
'' False
'0' True
[] False
[0] True
None False
0.0 False
La stringa "0" è truthy perché è una stringa non vuota. È un tranello per chi legge numeri dall'input e li verifica prima di convertirli. La pagina su numeri e booleani spiega il rapporto tra bool e int.
and e or restituiscono un operando
Ecco dove Python si distingue dalla maggior parte dei linguaggi. and e or non producono un nuovo True o False. Restituiscono uno dei due valori che gli hai dato:
x or yrestituiscexsexè truthy, altrimenti restituiscey.x and yrestituiscexsexè falsy, altrimenti restituiscey.
Quando entrambi gli operandi sono booleani, "restituire un operando" e "restituire un booleano" sono la stessa cosa: per questo la differenza passa inosservata finché non mescoli altri tipi.
not è l'eccezione: restituisce sempre True o False.
Se ti serve un vero booleano da un'espressione and/or, per esempio per salvarlo o restituirlo da una funzione che promette un bool, avvolgila in bool():
Valutazione in cortocircuito
Python valuta and e or da sinistra a destra e si ferma non appena conosce la risposta:
andsi ferma al primo valore falsy, perché niente di ciò che viene dopo può rendere vera l'intera espressione.orsi ferma al primo valore truthy, perché niente di ciò che viene dopo può rendere falsa l'intera espressione.
Il lato saltato non viene proprio eseguito. Puoi vederlo succedere con funzioni che stampano qualcosa quando vengono chiamate:
Output:
and:
checking A
False
or:
checking A
True
B non viene mai controllato in nessuno dei due casi. È il cortocircuito a rendere sicure le condizioni di guardia. La seconda metà di ciascuna condizione qui sotto andrebbe in crash da sola, ma viene eseguita solo dopo che la prima metà ha escluso il caso problematico:
Metti per primo il test più economico o quello protettivo. Invertendo l'ordine, user.startswith("admin") and user is not None solleva AttributeError quando user è None.
Schemi basati su or e and
Siccome or restituisce il suo primo operando truthy, ti dà un valore predefinito in una riga:
Output:
Hello, Ada!
Hello, guest!
Hello, guest!
Il problema è che or sostituisce ogni valore falsy, non solo None. Se 0, "" o [] sono input legittimi, or li butterà via:
Usa x if x is not None else default quando zero o vuoto sono valori validi. La pagina su if/else spiega questa espressione condizionale.
and ha uno schema corrispondente: "usa questo valore solo se il primo è impostato". È meno comune e spesso più chiaro scritto come if, quindi usalo con parsimonia:
Precedenza: prima not, poi and, poi or
Quando un'espressione mescola i tre operatori, Python applica prima not, poi and, poi or. I confronti come ==, < e in vengono applicati prima di tutti loro.
a or b and c e (a or b) and c danno risposte diverse con gli stessi valori, quindi una condizione mista dovrebbe avere le parentesi anche quando l'ordine predefinito è quello giusto. Non costano nulla e tolgono ogni dubbio a chi leggerà il codice dopo di te.
and/or contro &/|
& e | somigliano ad and e or e a volte danno la stessa risposta, ma sono operatori diversi.
and/orverificano la truthiness, vanno in cortocircuito e restituiscono uno degli operandi.&/|sono operatori bit a bit. Sugli interi combinano i bit dei due numeri. Sui set significano intersezione e unione. SuTrueeFalserestituiscono un booleano. Non vanno mai in cortocircuito: entrambi i lati vengono sempre valutati.
Gli operatori bit a bit hanno anche una precedenza più alta dei confronti, e questo trasforma una condizione scritta con & in tutt'altra cosa:
1 & y è 1 & 5, cioè 1, quindi la riga centrale diventa la catena 5 > 1 > 1, e 1 > 1 è falso. Nel normale codice Python, usa and, or e not per le condizioni.
L'unico caso in cui &, | e ~ sono corretti per le condizioni è NumPy e pandas. Un array contiene molti valori, quindi non ha un unico valore di verità, e and solleva ValueError: The truth value of an array ... is ambiguous. Le librerie ridefiniscono & e | per lavorare elemento per elemento: ecco perché i filtri di pandas hanno la forma df[(df.age > 18) & (df.country == "CA")], con le parentesi attorno a ogni confronto per il motivo di precedenza visto sopra.
any() e all(): and e or su una lista
Per combinare un'intera sequenza di condizioni, usa le funzioni integrate all() (un and su tutti gli elementi) e any() (un or su tutti gli elementi). Entrambe vanno in cortocircuito allo stesso modo:
A differenza di and e or, any() e all() restituiscono sempre un booleano.
Errori comuni
Confrontare una variabile con più valori usando or. Questa condizione è sempre vera:
Python legge la prima condizione come (color == "red") or "blue". Il confronto è False, quindi or restituisce "blue", una stringa non vuota, che è truthy. Ripeti il confronto su entrambi i lati o, meglio ancora, verifica l'appartenenza con in.
Scrivere && o ||. Sono entrambi un SyntaxError. Usa and e or.
Aspettarsi un booleano da and/or. x = a or b salva a o b stesso. Spesso è proprio ciò che vuoi, ma se una funzione deve restituire True o False, converti con bool().
Affidarsi alla precedenza nelle condizioni miste. a or b and c è legale e ben definito, ma aggiungi le parentesi così nessuno deve ricordarsi la regola.
Domande frequenti
Cosa fa l'operatore and in Python?
a and b è vero solo quando entrambi i lati sono veri. Python valuta prima a: se a è falsy restituisce a senza guardare b, altrimenti restituisce b. Con dei semplici booleani il risultato è quello solito: True and False è False.
Perché 0 or 5 restituisce 5 e non True?
0 or 5 restituisce 5 e non True?or e and restituiscono uno dei loro operandi, non un nuovo booleano. x or y restituisce x se x è truthy, altrimenti y. 0 è falsy, quindi 0 or 5 restituisce 5. Avvolgi l'espressione in bool() se ti serve un vero True o False.
Che differenza c'è tra and e & in Python?
and e & in Python?and è un operatore logico: verifica la truthiness e va in cortocircuito. & è un operatore bit a bit: sugli interi combina i bit (6 & 3 fa 2), sui set calcola l'intersezione e valuta sempre entrambi i lati. Usa and nelle condizioni degli if. L'eccezione sono NumPy e pandas, dove & è l'and elemento per elemento.
In Python viene prima and oppure or?
not ha la precedenza più alta, poi and, poi or. Quindi a or b and c significa a or (b and c), e not a or b significa (not a) or b. I confronti come == e < hanno precedenza più alta di tutti e tre.
Posso usare && e || in Python?
No. && e || in Python sono un SyntaxError. Gli operatori logici sono le parole and, or e not. Un singolo & o | è valido ma significa un'altra cosa (and/or bit a bit).