Ordenar listas en Python, con ejemplos


El proyecto de este post lo puedes descargar pulsando AQUI.

En el tutorial "List en Python, con ejemplos" hablamos del método "sort()" para la ordenación de los elementos de una lista que en ese caso los elementos eran datos atómicos y por tanto eran muy sencillos de ordenar. En este tutorial vamos a ver cómo ordenar elementos "no atómicos" (tuplas, objetos, etc.) de una lista o cómo ordenar una lista de strings a partir de un substring.

Recordemos en primer lugar el método "sort()":

nombreLista.sort(cmp=None, key=None, reverse=False)

Como vemos este método tiene 3 parámetros. El primero 'cmp' lo vamos a obviar ya que a este habría que pasarle una función de comparación de dos elementos y esto lo haremos con el segundo parámetro 'key' al que le indicaremos por que campo, valor, atributo, etc. queremos ordenar la lista. El tercer parámetro 'reverse' le indicaremos con un True o False si queremos que la ordenación sea de forma creciente (reverse=False) o decreciente (reverse=True). Por defecto sino definimos este parámetro la ordenación será de forma creciente.

Vamos a pasar con el primer ejemplo en el que vamos a tener una lista de tuplas:

# Lista de Tuplas
futbolistasTup = [(1, "Casillas"), (15, "Ramos"), (3, "Pique"), (5, "Puyol"), (11, "Capdevila"), (14, "Xabi Alonso"), (16, "Busquets"), (8, "Xavi Hernandez"), (18, "Pedrito"), (6, "Iniesta"), (7, "Villa")]

En este caso cada tupla contendrá en la primera posición el dorsal y en la segunda posición el nombre de los jugadores titulares de la selección Española que ganaron el mundial del 2010. En este primer ejemplo vamos a ordenar esta lista por el dorsal, es decir por la primera posición de la tupla. Para ello le indicamos al parámetro 'key' (con una función lambda) el valor por el que queremos ordenar la lista, que será la primera posición de cada una de las tuplas. Esto lo hacemos de la siguiente forma:

futbolistasTup.sort(key=lambda futbolista: futbolista[0])
print "Imprimimos las lista ordenada por dorsal:"
print futbolistasTup

Como salida a este fragmento de código tenemos la siguiente lista de tuplas ordenada por dorsal:

Imprimimos las lista ordenada por dorsal:
[(1, 'Casillas'), (3, 'Pique'), (5, 'Puyol'), (6, 'Iniesta'), (7, 'Villa'), (8, 'Xavi Hernandez'), (11, 'Capdevila'), (14, 'Xabi Alonso'), (15, 'Ramos'), (16, 'Busquets'), (18, 'Pedrito')]

Si quisiésemos ordenarlo por dorsal en orden decreciente solo tendríamos que pasale el parámetro 'reverse=True':

futbolistasTup.sort(key=lambda futbolista: futbolista[0], reverse=True)

Si ahora quisiésemos ordenar esta lista por nombre (en orden alfabético) habría que indicarle en la función lambda que lo compare por la segunda posición de la tupla:

futbolistasTup.sort(key=lambda futbolista: futbolista[1])
print "Imprimimos las lista ordenada por el nombre del jugador:"
print futbolistasTup

Como salida a este fragmento de código tenemos lo siguiente:

Imprimimos las lista ordenada por el nombre del jugador:
[(16, 'Busquets'), (11, 'Capdevila'), (1, 'Casillas'), (6, 'Iniesta'), (18, 'Pedrito'), (3, 'Pique'), (5, 'Puyol'), (15, 'Ramos'), (7, 'Villa'), (14, 'Xabi Alonso'), (8, 'Xavi Hernandez')]

Veamos ahora como trabajaríamos con una lista de Strings que contiene el dorsal y el nombre de los jugadores separados por un guión:

# Lista de Strings
futbolistas = ["1 - Casillas", "15 - Ramos", "3 - Pique", "5 - Puyol", "11 - Capdevila", "14 - Xabi Alonso", "16 - Busquets", "8 - Xavi Hernandez", "18 - Pedrito", "6 - Iniesta", "7 - Villa"]

Para este ejemplo vamos a ordenar la lista por el nombre del jugador alfabéticamente de forma decreciente. Para ello tenemos que definir en la función lambda que le pasamos al parámetro 'key' que ordene la lista por la segunda parte del String (el nombre) tras hacer un "split" del mismo por el caracter "-":

futbolistas.sort(key=lambda futbolista: futbolista.split("-")[1], reverse=True)
print "\nImprimimos las lista ordenada por el nombre del jugador:"
print futbolistas

Como salida a este fragmento de código tenemos lo siguiente:

Imprimimos las lista ordenada por el nombre del jugador:
['8 - Xavi Hernandez', '14 - Xabi Alonso', '7 - Villa', '15 - Ramos', '5 - Puyol', '3 - Pique', '18 - Pedrito', '6 - Iniesta', '1 - Casillas', '11 - Capdevila', '16 - Busquets']

Pasemos por último a ordenar una lista de objetos por un atributo determinado. Para ello vamos a definir la siguiente clase "Futbolista":

class Futbolista:

    def __init__(self, dorsal, nombre, demarcacion):
        self.dorsal = dorsal
        self.nombre = nombre
        self.demarcacion = demarcacion


    def __str__(self):
        return "%i - %s - %s" % (self.dorsal, self.nombre, self.demarcacion)

Como vemos cada objeto de la clase "Futbolista" tendrá 3 atributos (dorsal, nombre y demarcación) y accediendo a cada uno de estos atributos podremos ordenar una lista que contenga objetos de esta clase. Vamos a ver un ejemplo: Nos creamos una lista llamada "futbolistasOb" que contendrá los siguientes objetos:

from Futbolista import Futbolista

futbolistasOb = list()
futbolistasOb.append(Futbolista(1,'Casillas','Portero'))
futbolistasOb.append(Futbolista(15,'Ramos','Lateral Derecho'))
futbolistasOb.append(Futbolista(3,'Pique','Central'))
futbolistasOb.append(Futbolista(5,'Puyol','Central'))
futbolistasOb.append(Futbolista(11,'Capdevila','Lateral Izquierdo'))
futbolistasOb.append(Futbolista(14,'Xabi Alonso','Medio Centro'))
futbolistasOb.append(Futbolista(16,'Busquets','Medio Centro'))
futbolistasOb.append(Futbolista(8,'Xavi Hernandez','Centro Campista'))
futbolistasOb.append(Futbolista(18,'Pedrito','Interior Izquierdo'))
futbolistasOb.append(Futbolista(6,'Iniesta','Interior Derecho'))
futbolistasOb.append(Futbolista(7,'Villa','Delantero'))

Para ordenar esta lista de objetos de la clase "Futbolista" por el atributo dorsal, tenemos que "decirle" a la función lambda del parámetro 'key' que el campo de ordenación es el atributo dorsal (futbolista.dorsal). Esto lo hacemos de la siguiente forma:

futbolistasOb.sort(key=lambda futbolista: futbolista.dorsal)
print "Futbolistas ordenados por el atributo Dorsal"
for i in futbolistasOb:
    print i

Como salida a este fragmento de código tenemos lo siguiente:

Futbolistas ordenados por el atributo Dorsal
1 - Casillas - Portero
3 - Pique - Central
5 - Puyol - Central
6 - Iniesta - Interior Derecho
7 - Villa - Delantero
8 - Xavi Hernandez - Centro Campista
11 - Capdevila - Lateral Izquierdo
14 - Xabi Alonso - Medio Centro
15 - Ramos - Lateral Derecho
16 - Busquets - Medio Centro
18 - Pedrito - Interior Izquierdo

De igual forma (y viendo los ejemplos anteriores) podemos ordenar también a los futbolistas por el nombre; que en este caso lo haremos de forma descendente. Para ello le indicamos a la función lambda que lo haga por el atributo 'nombre' y con la opción de 'reverse=True':

futbolistasOb.sort(key=lambda futbolista: futbolista.nombre, reverse=True)
print "Futbolistas ordenados descendentemente por el atributo Nombre"
for i in futbolistasOb:
    print i

Como salida a este fragmento de código tenemos lo siguiente:

Futbolistas ordenados descendentemente por el atributo Nombre
8 - Xavi Hernandez - Centro Campista
14 - Xabi Alonso - Medio Centro
7 - Villa - Delantero
15 - Ramos - Lateral Derecho
5 - Puyol - Central
3 - Pique - Central
18 - Pedrito - Interior Izquierdo
6 - Iniesta - Interior Derecho
1 - Casillas - Portero
11 - Capdevila - Lateral Izquierdo
16 - Busquets - Medio Centro

En resumen, se ha explicado en esta entrada todo lo necesario para ordenar una lista en función de un determinado elemento, substring, atributo, etc. Lo importante de todo esto es saber que se le debe de indicar correctamente por medio del parámetro 'key' el campo por el que se quiere ordenar por medio de una función lambda que será la encargada de acceder (bien sea con un split, indicando la posición de una tupla, lista, diccionario, etc, atributo de un objeto, …) al elemento por el que se ha de ordenar.

Comparte esta entrada en:
Safe Creative #1401310112503
Ordenar listas en Python, con ejemplos por "www.jarroba.com" esta bajo una licencia Creative Commons
Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
Creado a partir de la obra en www.jarroba.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies

ACEPTAR
Aviso de cookies