En este tutorial te enseñaré cómo ordenar una lista en Python. En él verás los distintos modos que existen para ordenar un objeto de tipo list, desde el más simple al más complejo.
Índice
Ordenar una lista en Python con el método sort()
La forma más sencilla de ordenar una lista en Python es utilizar el método sort()
de la clase list
.
Este método modifica la propia lista, ordenando los elementos de manera ascendente (el método siempre devuelve None
):
>>> numeros = [16, 4, 9, 1, 3, 20, 8] >>> numeros.sort() >>> numeros [1, 3, 4, 8, 9, 16, 20] >>> palabras = ["hola", "coche", "avión", "manzana", "perro", "gato"] >>> palabras.sort() >>> palabras ['avión', 'coche', 'gato', 'hola', 'manzana', 'perro']
Para listas que contienen elementos de tipos heterogéneos, llamar a la función sort()
provocará que el intérprete lance un error.
>>> lista = [1, "a", 5, "g", 3, "c"] >>> lista.sort() Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: '<' not supported between instances of 'str' and 'int'
La función sorted()
Por otro lado, Python define la función incorporada sorted()
que se puede utilizar para ordenar cualquier iterable, no solo listas. Esta función es muy parecida al método sort()
pero, a diferencia de este, sí que devuelve una nueva lista.
Veamos un ejemplo:
>>> numeros = [16, 4, 9, 1, 3, 20, 8] >>> ordenados = sorted(numeros) >>> ordenados [1, 3, 4, 8, 9, 16, 20] >>> numeros [16, 4, 9, 1, 3, 20, 8]
Al igual que el método sort()
, llamar a sorted()
con una lista heterogénea de elementos hará que el intérprete lance un error.
Por defecto, tanto sort()
como sorted()
ordenan los elementos de manera ascendente, para lo cuál, aplican el operador <
.
A continuación, veremos cómo podemos modificar el modo en que ambos ordenan los elementos de una lista.
Parámetro reverse para ordenar de mayor a menor
Tanto al método sort()
como a la función sorted()
se le puede indicar el parámetro reverse
para modificar el orden ascendente en que se ordena una lista. Así, si se indica reverse=True
, el orden será de mayor a menor (por defecto es False
):
>>> numeros = [16, 4, 9, 1, 3, 20, 8] >>> numeros.sort(reverse=True) >>> numeros [20, 16, 9, 8, 4, 3, 1] >>> numeros = [16, 4, 9, 1, 3, 20, 8] >>> ordenados = sorted(numeros, reverse=True) >>> ordenados [20, 16, 9, 8, 4, 3, 1]
El parámetro key para indicar el valor de ordenación
Además de reverse
, al método sort()
y a la función sorted()
se le puede pasar el parámetro key
. Este parámetro debe ser una función que será invocada con cada elemento de la lista antes de hacer la comparación. Cualquier función que se pase en el parámetro key
debe tomar un único argumento y devolver una clave, que será el valor que se tenga en cuenta para realizar la comparación.
Este parámetro es especialmente útil a la hora de ordenar objetos complejos.
Uso de key con objetos iterables
Generalmente, lo que se suele hacer es devolver un índice del objeto como clave:
# Ordenar una lista de coches almacenados como tuplas >>> tuplas_coches = [ ('Rojo', '4859-A', 'A'), ('Azul', '2901-Z', 'M'), ('Gris', '1892-B', 'M') ] # Ordenar los coches por matrícula >>> ordenados = sorted(tuplas_coches, key=lambda coche : coche[1]) >>> ordenados [('Gris', '1892-B', 'M'), ('Azul', '2901-Z', 'M'), ('Rojo', '4859-A', 'A')] # Ordenar una lista de coches almacenados como diccionarios >>> diccionarios_coches = [ {'color': 'Rojo', 'matricula': '4859-A', 'cambio': 'A'}, {'color': 'Azul', 'matricula': '2901-Z', 'cambio': 'M'}, {'color': 'Gris', 'matricula': '1892-B', 'cambio': 'M'} ] >>> ordenados = sorted(diccionarios_coches, key=lambda coche : coche['matricula']) >>> ordenados [{'color': 'Gris', 'matricula': '1892-B', 'cambio': 'M'}, {'color': 'Azul', 'matricula': '2901-Z', 'cambio': 'M'}, {'color': 'Rojo', 'matricula': '4859-A', 'cambio': 'A'}]
Uso de key con clases
De igual modo, cuando se trabaja con clases y objetos se puede devolver un atributo como valor de key
.
class Coche: def __init__(self, color, matricula, cambio): self.color = color self.matricula = matricula self.cambio = cambio def __repr__(self): return repr((self.matricula, self.color, self.cambio)) >>> coches = [Coche('Rojo', '4859-A', 'A'), Coche('Azul', '2901-Z', 'M'), Coche('Gris', '1892-B', 'M')] >>> sorted(coches, key=lambda coche : coche.matricula) [('1892-B', 'Gris', 'M'), ('2901-Z', 'Azul', 'M'), ('4859-A', 'Rojo', 'A')]
Ordenar una lista utilizando las funciones del módulo operator
Las funciones vistas en la sección anterior que se pasan en el parámetro key
suelen tener un patrón común. Es por ello que Python proporciona una serie de funciones para que acceder a un elemento de una colección o acceder al atributo de un objeto sea fácil y rápido. Estas funciones son itemgetter()
y attrgetter()
, ambas del módulo operator
.
Retomando los ejemplos anteriores, se pueden modificar haciendo uso de estas funciones de la siguiente manera:
>>> from operator import itemgetter, attrgetter # Ordenar una lista de coches almacenados como tuplas >>> tuplas_coches = [ ('Rojo', '4859-A', 'A'), ('Azul', '2901-Z', 'M'), ('Gris', '1892-B', 'M') ] >>> sorted(tuplas_coches, key=itemgetter(1)) [('Gris', '1892-B', 'M'), ('Azul', '2901-Z', 'M'), ('Rojo', '4859-A', 'A')] >>> class Coche: def __init__(self, color, matricula, cambio): self.color = color self.matricula = matricula self.cambio = cambio def __repr__(self): return repr((self.matricula, self.color, self.cambio)) # Ordenar una lista de objetos de tipo Coche >>> coches = [Coche('Rojo', '4859-A', 'A'), Coche('Azul', '2901-Z', 'M'), Coche('Gris', '1892-B', 'M')] >>> sorted(coches, key=attrgetter('matricula')) [('1892-B', 'Gris', 'M'), ('2901-Z', 'Azul', 'M'), ('4859-A', 'Rojo', 'A')]
Además, a estas funciones se les puede pasar más de un parámetro para tener en cuenta más de un campo de ordenación.
En el siguiente ejemplo las tuplas de coches se ordenan por tipo de cambio y matrícula:
# Ordenar una lista de coches almacenados como # tuplas por tipo de cambio y número de matrícula >>> tuplas_coches = [ ('Rojo', '4859-A', 'A'), ('Azul', '2901-Z', 'M'), ('Gris', '1892-B', 'M') ] >>> sorted(tuplas_coches, key=itemgetter(2, 1)) [('Rojo', '4859-A', 'A'), ('Gris', '1892-B', 'M'), ('Azul', '2901-Z', 'M')]
Conclusión
Como has visto en este tutorial, existen varias formas de ordenar los elementos de una lista. No hay una mejor que otra, simplemente usa el modo que mejor se adecúe a cada situación.