1. Faro

Nivel 4 · Ordena productos con una key

La solicitud

De Thomas Whitaker, Director de Merchandising

“Para la franja «selección premium» de la página de inicio necesito estos productos del más caro al más barato. Cuando dos cuesten lo mismo, ponlos en orden alfabético para que el diseño sea estable.”

Tu objetivo

Asigna a result una lista de nombres de producto ordenados por precio de mayor a menor; los productos con el mismo precio se ordenan por nombre de la A a la Z.

  • Guarda una lista de 7 en resultpendiente

Tu código

Python

Cargando el editor…

    ResultadoPresiona Ejecutar para ver el tuyo

    Mote revisa tu resultado

    Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.

    La lección

    sorted y sort

    sorted() devuelve una lista ordenada nueva y deja la original intacta:

    sorted([189.0, 34.0, 1249.0])                 # [34.0, 189.0, 1249.0]
    sorted([189.0, 34.0, 1249.0], reverse=True)   # [1249.0, 189.0, 34.0]

    Las listas también tienen un método .sort() que ordena en el sitio y devuelve None. Prefiere sorted() cuando quieras conservar el orden original, que es lo habitual en análisis.

    Ordenar por una parte de cada elemento

    ¿Cómo se ordena una lista de diccionarios? Python no puede comparar dos diccionarios directamente. Le indicas qué comparar con una función key: una función que recibe un elemento y devuelve el valor por el que ordenar.

    def by_price(p):
        return p["price"]
    
    sorted(products, key=by_price)     # cheapest first

    Fíjate en key=by_price sin paréntesis. Estás pasando la función, y sorted la llama con cada producto.

    lambda: una función sin nombre

    Para keys de un solo uso, escribir un def completo es excesivo. Una lambda es una pequeña función anónima escrita en línea:

    sorted(products, key=lambda p: p["price"])

    lambda p: p["price"] significa «una función que recibe p y devuelve p["price"]». Está limitada a una sola expresión, lo cual es justo lo adecuado para las keys.

    Ordenar en dos niveles

    Para ordenar por precio y luego por nombre, devuelve una tupla desde la key. Python compara las tuplas elemento a elemento: primero el precio, y solo si los precios son iguales, el nombre.

    sorted(products, key=lambda p: (p["price"], p["name"]))

    Pero tú quieres el precio de mayor a menor y el nombre de la A a la Z. reverse=True invertiría ambos. El truco estándar con números es negar el que quieres descendente:

    sorted(products, key=lambda p: (-p["price"], p["name"]))

    -1249.0 es menor que -489.0, así que el producto más caro va primero, mientras que los nombres siguen ordenándose con normalidad. Para dos columnas de texto en direcciones opuestas, ordenarías dos veces (el orden de Python es estable, es decir, los elementos iguales conservan su orden existente), pero con números es, con diferencia, el caso común.

    Por qué importa el desempate

    Sin un desempate, los productos con el mismo precio se quedan en el orden en que llegaron. Ese orden puede cambiar entre exportaciones, así que una página de inicio, un informe o una prueba que compara listas «cambia» de repente sin ningún cambio real en los datos. Siempre que ordenes para mostrar o para una lista de los N mejores, añade un desempate que deje el orden totalmente determinado. En las entrevistas, mencionarlo sin que te lo pregunten es buena señal.

    Errores comunes

    • Usar products.sort() y luego asignar su valor de retorno, que es None.
    • Escribir key=lambda p: p["price"], reverse=True y obtener los nombres en los empates de la Z a la A.
    • Olvidar que necesitas nombres, no diccionarios completos, en la lista final.

    Una mirada hacia delante

    En pandas, la misma petición es products.sort_values(["unit_price", "name"], ascending=[False, True]), con una dirección distinta para cada columna.

    Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.