Sorting a list of objects in Python

Posted by in Python

To be honest, doing a sort of objects with Visual Basic 6 or almost other language can be a difficult task, and maybe it takes some times and several lines of code, but … in Python …. everything seem so easy … of course, if you know how to do it!

Sorting lists … of objects

The example I will describe on this entrance is how to sort a list of objects, so … let’s start by ordering a simple list. To do that, let’s use the built-in function sorted.

milista = [4,1,8,2,9]
print sorted(milista)

Easy, isn’t it?

Ordenar listas

Sort a list

Now, let’s increase difficulty, because what I would likee to sort is a list of objects. First, let’s define a function to print the results. Next, let’s define a object with two properties called campo1 y campo2. (campo means field in spanish)

One method to do that is by using the lambda function, like this:

vv2 = sorted(vv, key=lambda objeto: objeto.campo1)

 

The outcome, only using campo1 as a sort criteria is:

Ordenación de listas de objetos

Sort a list of objects

If you want to reverse the order, you need to include the parameter reverse=True.

Sorting a list of objects by more that one field

In the previous image you can check that the list is sort by campo1, but the perfect situatios is to sort by campo1, and in case the value is the same, use campo2. The best way to sort the list under this conditios is to use Python’s magic methods.

Magic methods? What are you talking about? If you don’t know what I’m talking about, it could be very useful for you to read this document: , because on this guide evetything related to magic methos is very well explained.

The case is … I need to modify the Ejemplo class, and define the comparation magic method, and here is where the logic will be applied. The modified class has this code:


class Ejemplo():
def __init__(self, campo1, campo2):
self.campo1 = campo1
self.campo2 = campo2
def __str__(self):
return "%s - %s" % (self.campo1, self.campo2)

def __cmp__(self, other):
if self.campo1 == other.campo1:
return 1 if self.campo2 > other.campo2 else -1
elif self.campo1 < other.campo1:
return -1
else:
return 1

The value 1 indicates that self is higher order than other. When returning 0 means that both objects hasve the same values, while the function returns -1 means that other is previous to self.

Now, you don’t need to specify the key parameter inside the sorted function, because what it will be applied is the magic method defined.

The outcome after the modification of the class is:

Ordenación de listas de objetos

Sort a list of objects

The full code is:


#-------------------------------------------------------------------------------
# Copyright:   (c)Manejando datos 2014
#-------------------------------------------------------------------------------
miVersion = "Ordenación de objetos con Python - version 0.2.0"

class Ejemplo():
def __init__(self, campo1, campo2):
self.campo1 = campo1
self.campo2 = campo2
def __str__(self):
return "%s - %s" % (self.campo1, self.campo2)

def __cmp__(self, other):
if self.campo1 == other.campo1:
return 1 if self.campo2 > other.campo2 else -1
elif self.campo1 < other.campo1:
return -1
else:
return 1

def lista(vv):
""" Imprimimos la lista"""
for v in vv:
print (v)

# Definimos varios objetos
v1 = Ejemplo("rojo", 10)
v2 = Ejemplo("rojo", 8)
v3 = Ejemplo("rojo", 16)
v4 = Ejemplo("rojo", 11)
v5 = Ejemplo("amarillo", 10)
v6 = Ejemplo("amarillo", 8)
v7 = Ejemplo("verde", 14)
v8 = Ejemplo("verde", 12)
v9 = Ejemplo("verde", 8)

# Creamos la Lista
vv = [v1, v2, v3, v4, v5, v6, v7, v8, v9]
vv2 = sorted(vv, key=lambda objeto: objeto.campo1, reverse=True)
#lista(vv2)
print " -------"
vv3 = sorted(vv)
lista(vv3)

In summary, sorting a list of objects is not a complex task any more, but as you can read, it requires more knowledge.

You can find the Python code on GitHub. Also, the Python editor I’m using on this example is PyScripter, an IDE I like a lot, and here you can read about it. In my opinion, for small scripts, is “almost” perfect!