Booleans, operadors lògics i de comparació a Python
Els booleans i els operadors lògics/comparatius són part del nucli del llenguatge. No només serveixen per a condicionals: es fan servir a validacions, filtres, comprovacions d’ estat i construcció d’ expressions més complexes. Entendre com funcionen, incloent-hi els seus matisos, evita errors difícils de detectar.
1. El tipus bool a Python
Python té un tipus nadiu per a valors booleans: bool. Els seus dos valors possibles són True i False.
x = True
y = False
print(type(x)) # <class 'bool'>
Internament, bool hereta d’ int:
isinstance(True, int) # True
int(True) # 1
int(False) # 0
Això significa que els booleans es comporten com a enters 1 i 0 a les operacions aritmètiques, tot i que a la majoria dels casos es fan servir com a valors lògics.
Advertència: Aquesta herència pot causar resultats inesperats:
True + True # 2
False * 10 # 0
No és un error, però convé no fer servir booleans amb intenció aritmètica llevat que sigui deliberat.
2. Operadors de comparació
2.1. Igualtat i desigualtat
- == Comprova si dos valors són iguals en valor.
- !=: Comprova si dos valors són diferents.
a = 5
b = 5.0
a == b # True, perquè 5 i 5.0 es consideren iguals en valor
a != b # False
Python compara segons el valor i, si és possible, converteix tipus de forma implícita (per exemple, int i float). Però no força conversió entre tipus incompatibles:
5 == "5" # False
Cas especial amb col·leccions:
[1, 2] == [1, 2] # True
[1, 2] is [1, 2] # False -> són dues llistes diferents en memòria
= = avalua el contingut, is avalua la identitat de l’ objecte. Són coses diferents.
2.2. Comparacions numèriques
Operadors:
- >: major que
- <: menor que
- > =: major o igual
- <=: menor o igual
3 > 2 # True
3 >= 3 # True
2 < 5 # True
2 <= 1 # False
Comparacions encadenades:
Python permet escriure:
x = 5
1 < x < 10 # True
Això no és simple: 1 < x < 10 s’avalua com (1 < x) and (x < 10). No s’avalua x dues vegades.
2.3. Comparació de cadenes
Les cadenes es comparen per ordre lexicogràfic (bàsicament, alfabètic segons el valor Unicode de cada caràcter).
"abc" < "abd" # True
"abc" > "Abc" # True, perquè l''a' minúscula té més valor Unicode que 'A'
Això significa que l’ordre depèn de majúscules i minúscules. Si vols comparar sense importar el cas:
"abc".lower() == "ABC".lower() # True
2.4. Comparació de col·leccions
A llistes, tuples i altres iterables comparables, Python compara element a element:
[1, 2, 3] < [1, 2, 4] # True
[1, 2] < [1, 2, 0] # False
Si tots els elements comparats són iguals i una seqüència és més curta, la més curta es considera menor.
3. Operadors lògics: and, or, not
3.1. and
Retorna el primer valor falsy o, si no n’hi ha cap, l’últim valor.
True and True # True
True and False # False
En expressions no booleanes:
"hola" and 123 # 123 (perquè tots dos són truthy, retorna l'últim)
"" and 123 # "" (primer valor falsy trobat)
Això es coneix com a avaluació de curtcircuit:
A and, si el primer operant és fals, no avalua el segon.
3.2. or
Retorna el primer valor truthy o, si no n’hi ha cap, l’últim valor.
True or False # True
False or False # False
En expressions no booleanes:
"" or "default" # "default"
0 or 99 # 99
A or, si el primer operant és veritable, no avalua el segon.
3.3. not
Inverteix el valor de veritat:
not True # False
not 0 # True (0 es falsy)
not "abc" # False (cadena no buida és truthy)
not sempre retorna un booleà pur (True o False), no un dels operands originals.
4. Valors truthy i falsy
A Python, qualsevol objecte pot avaluar-se en un context booleà (per exemple, en un if). Alguns valors es consideren falsy:
- False
- None
- Zero a qualsevol tipus numèric: 0, 0.0, 0j
- Seqüències i col·leccions buides: ”, [], {}, set(), range(0)
- Objectes el mètode especial dels quals __bool__() retorna False o __len__() retorna 0.
Tota la resta és truthy.
Exemple:
if []:
print("Llista amb elements")
else:
print("Llista buida") # S'executa això
5. Errors freqüents i matisos
5.1. Fer servir is en lloc de ==
a = 256
b = 256
a is b # True (per caché d' enters petits)
a == b # True
Amb strings i números petits pot coincidir per optimització interna, però no és segur. Per comparar valors, fes servir ==. is només per comparar identitat (mateix objecte en memòria) o amb None.
5.2. Confondre avaluació de curtcircuit amb retorn de booleans
and i or no retornen necessàriament True o False. Retornen un dels operands. Això és útil per assignar valors per defecte:
nom = input("Nom: ") or "Anònim"
Si l’usuari introdueix una cadena buida (“” → falsy), or retornarà “Anònim”.
5.3. Comparar múltiples valors incorrectament
A Python:
# Incorrecte
if x = = 1 or 2: # Sempre True, perquè 2 és truthy
El correcte:
if x = = 1 or x = = 2:
O millor:
if x in (1, 2):
5.4. Comparar tipus diferents que no són compatibles
Algunes comparacions que eren vàlides a Python 2 fallen a Python 3:
1 < "2" # TypeError
A Python 3 no es permet comparar tipus no relacionats llevat que tinguin mètodes especials que el defineixin explícitament.
6. Operadors combinats i expressions complexes
A Python, els operadors de comparació i lògics poden combinar-se de manera que es llegeixin d’esquerra a dreta. Això permet construir expressions complexes sense perdre llegibilitat si es fan servir amb cura.
Exemple:
edat = 25
te_carnet = True
si 18 <= edat <= 70 and te_carnet:
print("Pot conduir legalment")
Aquí es combinen comparacions encadenades amb and. L’ expressió es llegeix de forma natural:
- 18 < = edat < = 70 assegura que l’ edat està al rang.
- and te_carnet exigeix que la variable booleana sigui veritable.
Ordre d’ avaluació
L’ ordre de precedència principal:
- Comparacions (<, >, ==, etc.).
- not
- and
- or
Això significa que:
True or False and False
s’ avalua com:
True or (False and False) # → True
Si hi ha risc de confusió, el millor és fer servir parèntesis explícits.
7. Expressions condicionals compactes
Els booleans i operadors lògics es fan servir també per a condicionals en una sola línia, coneguts com a ternary expressions:
missatge = "Adult" if edat >= 18 else "Menor"
Això és equivalent a:
if edat > = 18:
missatge = "Adult"
else:
missatge = "Menor"
És útil quan l’ assignació és senzilla i es vol mantenir el codi compacte.
També es poden encadenar condicions:
estat = "nen" if edat < 12 else “adolescent" if edat < 18 else "adult"
Però si la lògica creix massa, és preferible un bloc if tradicional per no sacrificar llegibilitat.
8. Casos pràctics amb booleans i operadors
8.1. Filtrat de llistes
Fent servir and/or i operadors de comparació:
edats = [15, 22, 35, 18, 60, 75]
adults = [e for e in edats if e >= 18 and e < 65]
print(adults) # [22, 35, 18, 60]
8.2. Valors per defecte amb or
config_port = user_port or 8080
Si user_port és 0 o None, s’ assignarà 8080.
Advertència: Això també descarta valors vàlids que siguin falsy, com 0. Si vols permetre 0, cal fer servir una comprovació explícita:
config_port = 8080 if user_port is None else user_port
8.3. Verificació d’entrades
entrada = input("Escriu 'sí' per continuar: ").strip().lower()
if entrada in ("sí", "si", "yes", "y"):
continuar = True
else:
continuar = False
Aquí in reemplaça diverses comparacions == unides amb or.
8.4. Avaluació peresosa (short-circuiting) per evitar errors
usuari = {"nom": "Anna", "edat": 30}
# Evita error KeyError si no existeix 'email'
if "email" in usuari and usuari["email"].endswith("@exemple.com"):
print("Correu electrònic vàlid")
and evita que s’intenti accedir a usuari[“email”] si no existeix. Això és molt útil a les validacions.
9. Booleans com a resultat de funcions
Moltes funcions i mètodes a Python retornen booleans directament. Això permet encadenar comprovacions:
text = "Python"
if texto.isalpha() and text.islower():
print("Només lletres minúscules")
També és comú que funcions retornin valors truthy/falsy sense ser True o False:
resultat = re.search(r"\d+", "abc123")
if resultat:
print("S’han trobat números")
Aquí resultat és un objecte Match (truthy) si hi ha coincidència, o None (falsy) si no n’hi ha.
10. Patró de “ guard clauses ” amb booleans
En lloc d’ aniar condicionals:
if usuari_actiu:
if te_permis:
realitzar_accio()
Es poden fer servir guard clauses per sortir aviat:
if not usuari_actiu or not te_permis:
return
realitzar_accio()
Aquest patró es recolza en operadors lògics per simplificar el flux.
11. Reordenació d’expressions booleanes complexes
Quan una condició es torna difícil de llegir, el més útil és separar-la en variables intermèdies:
edat_valida = 18 <= edat <= 70
carnet_valid = te_carnet
permis_vigent = carnet_no_caducat
if edat_valida and carnet_valid and permiso_vigent:
...
Això no només facilita la lectura, també permet imprimir valors intermedis durant la depuració.
12. Resum de errors comuns
- Fer servir is en lloc de ==: només fer servir is per identidat o amb None.
- Oblidar que and i or retornen operands: pot ser útil o problemàtic segons el context.
- Avaluació peresosa ignorada: and i or no sempre avaluen tots els operands.
- Falsy que no són False: 0, “”, [], {}, None s’avaluen com a falsos.
- Comparacions múltiples mal formades: if x = = 1 or 2 és incorrecte; fer servir in.
13. Conclusió
Dominar els booleans i operadors a Python va més enllà de conèixer la sintaxi. Implica saber com es comporten amb diferents tipus de dades, com interactuen amb l’ avaluació de curtcircuit, i com aprofitar aquests comportaments per escriure codi més clar i segur. Fets servir amb precisió, permeten expressar condicions complexes de forma llegible i eficient.

