Batteries Included - 2014.09.08

list.sort() and sorted

Python offers two built-in options for sorting lists. The first is a built in method sort on the list type. This is a destructive operation in that it modifies your original list.

The second is a function sorted that returns a new sorted list from any iterable object.

Another approach is to implement "rich comparison" methods in your classes (<, >, <=, >=, ==, !=)


In [ ]:
names = ["George", "Paul", "John", "Ringo"]
print("Pre-sort {0}".format(names))
names.sort()
print("Post-sort {0}".format(names))
names.sort(reverse=True)
print("Reverse sort {0}".format(names))

In [ ]:
class Quarterback(object):
    
    def __init__(self, name=None, team=None, games_played=None, qb_rating=None, completions=None, attempts=None):
        self.name = name
        self.team = team
        self.games_played = int(games_played)
        self.qb_rating = float(qb_rating)
        self.completions = int(completions)
        self.attempts = int(attempts)
    
    @property
    def average_attempts_per_game(self):
        return self.attempts / self.games_played
    
    def __lt__(self, other):
        return (self.qb_rating < other.qb_rating)

    def __repr__(self):
        return "<Quarterback:{0}>".format(self.name)

In [ ]:
from csv import reader
quarterbacks = []
with open('qbdata.csv') as infile:
    for (index, line) in enumerate(reader(infile)):
        if index == 0:
            continue # skip header row
        if int(line[2]) < 2:
            continue # minimum 2 games played
        quarterbacks.append(Quarterback(name=line[0],
                                        team=line[1],
                                        games_played=line[2],
                                        qb_rating=line[3],
                                        completions=line[4],
                                        attempts=line[5]))

In [ ]:
sorted_by_qbr = sorted(quarterbacks, key=lambda x: x.qb_rating, reverse=True)

In [ ]:
["{0} ({1}) {2} QBR.".format(qb.name, qb.team, qb.qb_rating) for qb in sorted_by_qbr][:10]

In [ ]:
sorted_by_team = sorted(quarterbacks, key=lambda x: x.team)

In [ ]:
["{0} ({1}) {2} QBR.".format(qb.name, qb.team, qb.qb_rating) for qb in sorted_by_team][:10]

Let's make use of our lt method


In [ ]:
len(quarterbacks)
print quarterbacks[0]
quarterbacks.sort()
print quarterbacks[0]
quarterbacks.sort(reverse=True)
print quarterbacks[0]

In [ ]: