AulaML Python · C++
Python principiante · 28 min · Introducción a Python

Operadores y expresiones

Aritmética, comparaciones, lógica booleana y el orden exacto en que Python evalúa cada símbolo

Una expresión combina valores y operadores para producir un resultado nuevo. En esta lección dominas la aritmética de Python, las comparaciones, la lógica con cortocircuito, la diferencia entre `is` y `==`, la precedencia y los operadores que además asignan, como `+=` y `:=`.

Lección 3 de 3 del módulo
Al terminar esta lección podrás
  • Calcular con los operadores aritméticos y explicar la diferencia entre `/`, `//` y `%`
  • Construir condiciones con comparaciones encadenadas y operadores lógicos
  • Predecir el resultado de una expresión aplicando la precedencia
  • Distinguir igualdad de identidad y saber cuándo usar `==` y cuándo `is`
  • Usar asignación aumentada y el operador morsa sin perder legibilidad

Antes necesitas: Variables y tipos de datos

En esta lección
  1. ¿Qué es un operador y qué es una expresión?
  2. ¿Para qué sirven?
  3. ¿Cómo funciona por dentro? Precedencia y asociatividad
  4. Sintaxis: los operadores aritméticos
  5. Comparaciones: preguntas que devuelven bool
  6. Operadores lógicos y cortocircuito
  7. Identidad frente a igualdad: `is` y `==`
  8. Asignación aumentada y operador morsa
  9. Ejemplo básico: dividir una cuenta
  10. Ejemplo intermedio: promedio ponderado
  11. Caso práctico: repartir fotos en paquetes
  12. Visualización: cómo se reparte la cuenta
  13. Errores comunes
  14. Buenas prácticas
  15. Ejercicios
  16. Soluciones explicadas
  17. Resumen
  18. Evaluación

Ya sabes guardar valores. El siguiente paso es transformarlos: sumar dos precios, comprobar si una nota llega al mínimo, decidir si un cliente cumple dos requisitos. Todo eso se escribe con operadores, los símbolos que conectan valores y producen un resultado nuevo.

Esta lección es corta en teoría y larga en consecuencias. Un error de precedencia o un = donde iba == puede cambiar por completo el comportamiento de un programa que parece correcto a simple vista.

¿Qué es un operador y qué es una expresión?

Un operador es un símbolo que opera sobre uno o más valores llamados operandos. En 7 + 2, el operador es + y los operandos son 7 y 2. Una expresión combina valores, nombres y operadores y se reduce a un único valor: precio * cantidad, not activo, 0 < nota <= 20.

Piensa en los operadores como los verbos de la frase: los valores son sustantivos y el operador dice qué se hace con ellos. a + b no es una orden que desaparece: es una expresión que devuelve un valor que puedes imprimir, guardar o combinar con otro.

¿Para qué sirven?

Casi todo lo que hace un programa útil pasa por un operador. Estos son los usos que verás una y otra vez:

  • Calcular totales: subtotal + igv, precio * cantidad, total / meses.
  • Validar datos: 0 <= nota <= 20, stock > 0, correo != "".
  • Combinar requisitos: edad >= 18 and tiene_dni.
  • Acumular: total += venta dentro de un bucle.
  • Machine Learning: normalizar es (x - media) / desviacion; una predicción binaria se decide con probabilidad >= 0.5.

¿Cómo funciona por dentro? Precedencia y asociatividad

Python analiza la expresión, construye un árbol donde cada operador tiene como hijos sus operandos y lo evalúa de abajo hacia arriba. El orden lo decide la precedencia: cuanto más arriba está un operador en la tabla, antes se aplica.

PrioridadOperadoresEjemploResultado
1 (mayor)**2 ** 3 ** 2512, porque asocia a la derecha
2*, /, //, %7 // 2 * 39
3+, -2 + 3 - 14
4<, <=, >, >=, ==, !=0 < 5 <= 5True
5notnot TrueFalse
6andTrue and FalseFalse
7 (menor)orFalse or TrueTrue

Cuando dos operadores tienen la misma prioridad, casi todos asocian por la izquierda: 100 / 10 / 2 es (100 / 10) / 2, o sea 5.0. La potencia asocia por la derecha: 2 ** 3 ** 2 es 2 ** 9, no 8 ** 2. Ante la duda, escribe paréntesis.

Sintaxis: los operadores aritméticos

Son siete y cada uno responde una pregunta distinta. +, - y * se comportan como esperas; los otros cuatro merecen atención.

PYTHON aritmetica.py
print(7 / 2)
print(7 // 2)
print(7 % 2)
print(2 ** 10)
print(-7 // 2, -7 % 2)
  • 7 / 2 da 3.5: la división normal siempre devuelve float.
  • 7 // 2 da 3: división entera, descarta la parte decimal.
  • 7 % 2 da 1: el resto de la división entera.
  • 2 ** 10 da 1024: potencia.
  • -7 // 2 da -4 y -7 % 2 da 1: con negativos, // redondea hacia menos infinito y el resto conserva el signo del divisor.

La relación entre // y % es útil para recordar: a == (a // b) * b + (a % b). Con a = 47 y b = 6, 47 // 6 es 7, 47 % 6 es 5, y 7 * 6 + 5 vuelve a dar 47. Esa pareja sirve para repartir unidades en paquetes y saber cuántas sobran.

Comparaciones: preguntas que devuelven bool

Los operadores de comparación (==, !=, <, <=, >, >=) comparan dos valores y producen True o False. Python permite encadenarlos, y la cadena se lee como una conjunción: 0 < nota <= 20 equivale a 0 < nota and nota <= 20, pero evalúa nota una sola vez.

PYTHON comparaciones.py
print(1 == 1.0)
print("a" < "b")
print(0 < 16 <= 20)
print(10 != 10)

1 == 1.0 es True: la igualdad compara valores numéricos, no tipos. "a" < "b" compara códigos de caracteres y da True. 0 < 16 <= 20 se lee como una sola pregunta. 10 != 10 es False. Nunca escribas x = 5 en una comparación: = asigna y == compara.

Operadores lógicos y cortocircuito

and, or y not combinan valores lógicos. and es verdadero solo si ambos lados lo son; or lo es si al menos uno lo es; not invierte. Lo importante ocurre con el cortocircuito: si el lado izquierdo ya decide el resultado, Python no evalúa el derecho.

PYTHON logica.py
a = 10
b = 0

print(b != 0 and a / b > 2)
print(b == 0 or a / b > 2)
print(not b)

La línea 4 imprime False sin lanzar ZeroDivisionError: como b != 0 es falso, and no mira la división. La línea 5 también evita el error porque b == 0 ya decide. La línea 6 imprime True: 0 es falso y not lo invierte. Ese orden es la base de las guardas que protegen cálculos peligrosos.

Identidad frente a igualdad: `is` y `==`

== pregunta «¿valen lo mismo?». is pregunta «¿son exactamente el mismo objeto en memoria?». Para enteros pequeños y cadenas cortas, Python reutiliza objetos y is puede dar True por casualidad; con listas construidas por separado, no.

PYTHON identidad.py
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)
print(a is b)
print(a is c)

La salida es True, False, True. a y b tienen el mismo contenido pero son listas distintas; c es otra etiqueta del mismo objeto que a. Usa == para valores y reserva is para None, True y False. if x is None es correcto; if x == None funciona pero se considera mal estilo.

Asignación aumentada y operador morsa

total += venta equivale a total = total + venta, pero evalúa el destino una sola vez y comunica mejor la idea de acumular. Existen -=, *=, /=, //=, %= y **=. Con textos, += concatena; con listas, extiende.

PYTHON acumular.py
stock = 12
stock -= 5
precio = 45.5
precio *= 2

print(stock, precio)

stock pasa de 12 a 7 y precio de 45.5 a 91.0. Cada operador trabaja con los tipos de sus operandos: int menos int da int, y float por int da float. El operador morsa := (Python 3.8+) asigna dentro de una expresión y devuelve el valor, lo que evita calcular dos veces.

PYTHON morsa.py
stock = 12

if (restante := stock - 5) > 5:
    print(f"Quedan {restante} unidades")

print(restante * 2)

restante se calcula una vez, se compara con 5 y queda disponible para el resto del bloque; no hace falta repetir stock - 5. Imprime Quedan 7 unidades y luego 14. El morsa es útil cuando necesitas el valor de una condición más de una vez; en expresiones largas, resta legibilidad.

Ejemplo básico: dividir una cuenta

Cuatro amigos pagan una cena de 187.5 soles y dejan 10 % de propina. El total se reparte en partes iguales. Cada operador interviene en un paso distinto:

PYTHON cuenta.py
cuenta = 187.5
personas = 4
propina = cuenta * 0.10
total = cuenta + propina
por_persona = total / personas

print(total, round(por_persona, 2))

cuenta * 0.10 da 18.75; la suma da 206.25; la división entre 4 da 51.5625, que round reduce a 51.56. La multiplicación se ejecuta antes que la suma aunque no haya paréntesis, porque tiene mayor precedencia. Si solo se repartiera la cuenta sin propina, dividirías cuenta / personas y obtendrías 46.875.

Ejemplo intermedio: promedio ponderado

Un curso pondera prácticas al 30 %, examen al 30 % y proyecto al 40 %. Además, se aprueba solo si el promedio llega a 13 y el examen llega a 10. Aquí se combinan aritmética, comparación y lógica en dos líneas.

PYTHON promedio.py
practicas = 16
examen = 14
proyecto = 18

promedio = practicas * 0.30 + examen * 0.30 + proyecto * 0.40
aprueba = promedio >= 13 and examen >= 10

print(f"Promedio: {promedio:.2f}")
print(f"¿Aprueba? {aprueba}")

Los productos suman 4.8 + 4.2 + 7.2 = 16.2, que se muestra como 16.20. La condición evalúa primero promedio >= 13 (True), luego examen >= 10 (True), y and devuelve True. Si el examen fuera 9, el promedio no cambiaría pero aprueba sería False.

Caso práctico: repartir fotos en paquetes

Un cliente pide imprimir 47 fotos. Se venden en paquetes de 6 a 4.5 soles y las sueltas a 1.2 soles. Necesitas los paquetes completos, las fotos que sobran y el costo con IGV.

PYTHON pedido.py
fotos = 47
por_paquete = 6

paquetes = fotos // por_paquete
sueltas = fotos % por_paquete
costo = paquetes * 4.5 + sueltas * 1.2
costo_final = round(costo * 1.18, 2)

print(f"Paquetes: {paquetes} | Sueltas: {sueltas}")
print(f"Total con IGV: S/ {costo_final}")

47 // 6 es 7 y 47 % 6 es 5, porque 7 * 6 + 5 = 47. El costo base es 31.5 + 6.0 = 37.5; con IGV, 44.25. round(..., 2) corta el ruido de la coma flotante y la f-string final ya no necesita formato.

Visualización: cómo se reparte la cuenta

Ejecución visual ·Reparto paso a paso
1 / 6
1 cuenta = 187.5
2 personas = 4
3 propina = cuenta * 0.10
4 total = cuenta + propina
5 por_persona = round(total / personas, 2)
6 print(por_persona)
Se guarda el float 187.5 en cuenta.
Variables
cuenta = 187.5
Salida
—

Avanza paso a paso: observa la línea resaltada, las variables y la salida.

Errores comunes

Mensaje o síntomaPor qué ocurreCómo se arregla
ZeroDivisionError: division by zeroDividiste entre 0, quizá con un dato vacíoComprueba el divisor antes: if b != 0
TypeError: unsupported operand type(s) for +: 'int' and 'str'Mezclaste número y texto en una operaciónConvierte con int(), float() o str()
TypeError: '>' not supported between instances of 'str' and 'int'Comparaste un texto con un númeroConvierte el texto o revisa de dónde viene el dato
El resultado es False cuando esperabas TruePrecedencia: not a and b se lee (not a) and bAñade paréntesis explícitos
SyntaxError: invalid syntax en una comparaciónEscribiste = en lugar de ==Usa == para comparar
`is` no compara contenido
Incorrecto
PYTHON Frágil
nombre = "Ada"
print(nombre is "Ada")  # puede ser True o False
Correcto
PYTHON Correcto
nombre = "Ada"
print(nombre == "Ada")  # siempre True

`is` compara identidad: si son el mismo objeto. El intérprete puede reutilizar cadenas cortas y hacer que `is` dé `True` por casualidad, pero no es una garantía del lenguaje. Para contenido, usa siempre `==`; reserva `is` para `None`, `True` y `False`.

Buenas prácticas

  • Escribe paréntesis cuando mezcles and, or y not: nadie debería recordar la tabla de precedencia.
  • Usa == para valores e is solo con None, True y False.
  • No compares float con ==; usa abs(a - b) < 1e-9.
  • Prefiere // y % a conversiones cuando repartes unidades.
  • Evita cadenas largas sin nombres intermedios: se depuran peor.
  • Deja espacios alrededor de los operadores: a + b.

Ejercicios

Ejercicio 1

Promedio ponderado con dos decimales

Un alumno obtuvo 15 en prácticas, 18 en el examen y 12 en el proyecto. Las ponderaciones son 20 %, 50 % y 30 %. Calcula el promedio y muéstralo con dos decimales. Después comprueba si llega a 14 usando una comparación guardada en una variable booleana.
Pista

Multiplica cada nota por su peso, suma los tres productos y aplica :.2f al imprimir. Para la comparación, guarda el resultado en una variable.

Ejercicio 2

Minutos a horas y minutos

Guarda 347 en total_minutos, calcula las horas completas y los minutos sobrantes, y muestra 347 minutos = 5 h 47 min. Resuélvelo solo con // y %.
Pista

Una hora tiene 60 minutos: las horas completas son la división entera y el resto son los minutos sobrantes.

Completar código Completa la expresión
precio = 120
descuento = precio  0.10
total = precio - descuento

print(total  100)
print(total > 100  total < 120)

El descuento es un porcentaje del precio; las dos comparaciones deben cumplirse a la vez.

Soluciones explicadas

En el promedio ponderado, el error habitual es dividir entre 3 al final. Con pesos que ya suman 1 (0.20 + 0.50 + 0.30), no hay que dividir: cada nota ya está escalada. Si los pesos fueran enteros (20, 50, 30), dividirías entre 100. Comprueba que sumen 1 antes de confiar en el resultado.

En el ejercicio de minutos, // y % son complementarios: el cociente dice cuántas unidades completas caben y el resto, cuánto sobra. La misma idea convierte céntimos a soles o reparte artículos en cajas. No uses round aquí: redondear 5.78 a 6 horas sería incorrecto.

Resumen

  • Un operador combina operandos y produce un valor; una expresión es la combinación completa.
  • / siempre devuelve float; // descarta decimales; % da el resto.
  • Con negativos, // redondea hacia menos infinito y % conserva el signo del divisor.
  • Las comparaciones devuelven bool y se encadenan: 0 <= nota <= 20.
  • and y or cortocircuitan: el lado derecho solo se evalúa si hace falta.
  • == compara valores; is compara identidad y se reserva para None, True y False.
  • La precedencia va de ** a or; usa paréntesis ante la duda.
  • += acumula y := asigna dentro de una expresión (3.8+).

Evaluación

Evaluación 1

¿Qué imprime print(7 // 2, 7 % 2)?

Evaluación 2

¿Cuál es el valor de 2 + 3 * 4 ** 2?

Evaluación 3

¿Qué devuelve 0 or "sin dato"?

Tus notas

¿Ya lo entendiste?

Márcala como completada para llevar tu progreso y desbloquear el siguiente paso de la ruta.