Python Quiz 14 – Sorted en Python
Pregunta principal del PyQuiz:
films = [
{'title': "Doctor Strange", 'year': 2016},
{'title': 'Iron Man', 'year': 2008},
{'title': 'Ant-Man', 'year': 2015},
{'title': 'Thor', 'year': 2011},
]
ordered_films = sorted(films, key=lambda x: x['year'])
films_names = [x['title'] for x in ordered_films]
print(films_names)
--- ?? ---
a = ['Iron Man', 'Ant-Man', 'Doctor Strange', 'Thor']
b = ['Iron Man', 'Thor', 'Ant-Man', 'Doctor Strange']
c = RuntimeError
Concepto y explicación
En este PyQuiz se puede ver cómo usar sorted
para ordenar una lista de diccionarios en Python.
El uso de sorted es muy extendido por su versatilidad porque no solo se puede aplicar a listas sino a cualquier tipo de secuencias como veremos a lo largo de este pyquiz.
Uso de sorted
para listas en Python
Principalmente sorted convierte cualquier secuencia en una lista ordenada haciendo uso del comparador por defecto y del tipo de dato.
Un caso muy simple es ordenar las listas de números:
>>> sorted([4, 5, 7, 4, 2.9, 1])
[1, 2.9, 4, 4, 5, 7]
>>> sorted(x * 3 for x in range(5))
[0, 3, 6, 9, 12]
>>> import random
>>> sorted(random.randint(5, 10) * 3 for x in range(5))
[15, 15, 21, 24, 27]
>>> sorted(random.randint(5, 10) * 3 for x in range(5))
[15, 15, 15, 18, 27]
>>> sorted(random.randint(5, 10) * 3 for x in range(5))
[21, 21, 24, 27, 30]
Pero no sólamente se puede utilizar para números sino también para otros tipos de datos como ordenar listas de cadenas o listas de diferentes tipos de datos:
>>> sorted(['pepe', 'juan', 'alfredo', 'maría', 'antonia'])
['alfredo', 'antonia', 'juan', 'maría', 'pepe']
>>> sorted(['pepe', 'juan', 'alfredo', 'maría', 'antonia'], reverse=True)
['pepe', 'maría', 'juan', 'antonia', 'alfredo']
>>> sorted([4, 5, 7, True, False, 4, 2.9, 1], reverse=True)
[7, 5, 4, 4, 2.9, True, 1, False]
Pero si el comparador entre elementos no está definido (por usar tipos de datos que no se pueden comparar como números enteros y complejos) o se pretende usar un tipo de ordenación específico (como en el ejercicio) se utiliza el argumento key
.
Haciendo uso del argumento key, se puede especificar una función de ordenación y normalmente se utiliza una función lambda
aunque no es necesario y puede usarse una función normal:
>>> sorted([4, 5 + 3j])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'complex' and 'int'
>>> sorted([4, 5 + 3j], key=lambda x: x.real)
[4, (5+3j)]
>>> sorted(['pepe', 'maría', 'juan', 'antonia', 'alfredo'], key=lambda x: ('a' in x, x))
['pepe', 'alfredo', 'antonia', 'juan', 'maría']
>>> # ordenar dando prioridad a las palabras con menos de 5 caracteres
>>> sorted(['pepe', 'maría', 'juan', 'antonia', 'alfredo'], key=lambda x: (len(x) > 5, x))
['juan', 'maría', 'pepe', 'alfredo', 'antonia']
Como se puede ver en el ejemplo, se puede ordenar por cualquier lógica y si se devuelve una tupla, se puede ordenar con varios elementos a la vez.
Uso de sorted
para diccionarios, cadenas y reverse
Se ha comentado el uso de sorted
para listas pero cuando hay objetos más complejos como puedan ser diccionarios u objetos en general también se pueden ordenar usando key
>>> films = [
... {'title': "Doctor Strange", 'year': 2016},
... {'title': 'Iron Man', 'year': 2008},
... {'title': 'Ant-Man', 'year': 2015},
... {'title': 'Thor', 'year': 2011},
... ]
>>> ordered_films = sorted(films, key=lambda x: x['year'])
>>> print(ordered_films)
[
{'title': 'Iron Man', 'year': 2008},
{'title': 'Thor', 'year': 2011},
{'title': 'Ant-Man', 'year': 2015},
{'title': 'Doctor Strange', 'year': 2016}
]
>>> ordered_by_titles = sorted(films, key=lambda x: x['title'])
>>> ordered_by_titles
[
{'title': 'Ant-Man', 'year': 2015},
{'title': 'Doctor Strange', 'year': 2016},
{'title': 'Iron Man', 'year': 2008},
{'title': 'Thor', 'year': 2011}
]
También se pueden utilizar para ordenar palabras por orden alfabético como en los siguientes ejemplos:
>>> sorted('el perro de San Roque')
[' ', ' ', ' ', ' ', 'R', 'S', 'a', 'd', 'e', 'e', 'e', 'e', 'l', 'n', 'o', 'o', 'p', 'q', 'r', 'r', 'u']
>>> sorted('zoquete')
['e', 'e', 'o', 'q', 't', 'u', 'z']
>>> sorted('zoquete', reverse=True)
['z', 'u', 't', 'q', 'o', 'e', 'e']
Por defecto se ordena de forma ascendente pero también se puede ordenar de forma inversa simplemente añadiendo el argumento reverse=True
>>> sorted(films, key=lambda x: x['title'], reverse=True)
[
{'title': 'Thor', 'year': 2011},
{'title': 'Iron Man', 'year': 2008},
{'title': 'Doctor Strange', 'year': 2016},
{'title': 'Ant-Man', 'year': 2015}
]
>>> sorted(films, key=lambda x: x['year'], reverse=True)
[
{'title': 'Doctor Strange', 'year': 2016},
{'title': 'Ant-Man', 'year': 2015},
{'title': 'Thor', 'year': 2011},
{'title': 'Iron Man', 'year': 2008}
]
Por tanto en nuestra pregunta inicial se puede deducir que el resultado de la pregunta es: ['Iron Man', 'Thor', 'Ant-Man', 'Doctor Strange']
Solución
Por tanto la solución correcta es la B:
B) ['Iron Man', 'Thor', 'Ant-Man', 'Doctor Strange']
Practica Python con PyQuizzes
En la sección de PyQuizzes puedes encontrar ejercicios prácticos explicados pormenorizado para mejorar tus habilidades como pythonista. ¡No te los pierdas!
Tutorial Python online
Aprender Python de forma gratuita siguiendo las secciones del tutorial de Python.
Libros recomendados para aprender Python
Estos son los libros que pueden ayudarte a aprender Python, aprender a programar, tipos de datos, algoritmia y mucho más.