La solicitud

De Thomas Whitaker, Director de Merchandising
Tu objetivo
Corrige apply_markdown para que devuelva una lista nueva de precios reducidos pct por ciento (cada uno redondeado a 2) sin cambiar la lista que recibe. Asigna a result un diccionario con dos claves: 'list' (el list_prices original, sin cambios) y 'sale' (los precios rebajados).
- Guarda un dict en
resultpendiente
Tu código
Cargando el editor…
Solución de referencia
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Thomas, y por qué
La lección
Dos nombres, una lista
Cuando llamas a apply_markdown(list_prices, 20), Python no copia la lista. El parámetro prices pasa
a ser un segundo nombre para el mismo objeto lista. Todo lo que la función haga a prices[i]
también le ocurre a list_prices:
a = [369.00, 159.00]
b = a # no copy: two names for one list
b[0] = 295.20
a # [295.2, 159.0]
Los números y los strings no se pueden cambiar en el sitio, así que con ellos esto nunca da problemas.
Las listas y los diccionarios sí, y de ahí viene la sorpresa. El bucle del starter con
range(len(prices)) recorre las posiciones 0 a 4 y escribe cada precio de rebaja de vuelta en la lista
de quien llama, por eso las columnas «list» y «sale» salieron idénticas. No saltó ningún error; el daño
solo se vio en los números.
Devuelve una lista nueva
El patrón seguro es una función que lee su entrada y construye una salida nueva. Una list comprehension lo hace en una línea:
def apply_markdown(prices, pct):
return [round(p * (1 - pct / 100), 2) for p in prices]
Después de la corrección, list_prices sigue conteniendo 369.00, 159.00, 72.99, 27.99 y 44.99, y los
precios de rebaja son 295.20, 127.20, 58.39, 22.39 y 35.99. Puedes volver a ejecutar la función con 25%
y obtener una segunda respuesta correcta, porque la primera vez no se sobrescribió nada.
Si de verdad necesitas un bucle, copia primero con prices = list(prices) al principio de la función y
luego edita la copia. Escribir una lista nueva suele ser más sencillo.
Cómo detectar este tipo de error
El síntoma es siempre el mismo: datos que no tocaste cambian después de llamar a una función. Dos
comprobaciones rápidas lo encuentran. Imprime la entrada antes y después de la llamada, y busca dentro
de la función asignaciones sobre un argumento (prices[i] = ..., row["x"] = ...) o métodos que lo
cambian en el sitio, como .append(), .sort() o .pop().
Errores comunes
- Devolver
prices.copy()al final. El bucle ya había cambiado el original. - Escribir
sale_prices = list_pricesantes de la llamada y pensar que es una copia. Es un segundo nombre. - Usar
list_prices.sort()dentro de una función de informe, lo que reordena la lista de quien llama para siempre.
¡Linterna encendida!
Practicaste: debuggingfunctionsmutabilitylistsrange
- Resuelto
- Sin pistas
- Al primer intento
