dbmitch dbmitch - 1 month ago 7
Python Question

Sorting parallel lists in python - first item descending, second item ascending

I have two lists - one for a team name and the second for points

I wanted to sort them based on the points without losing track of the corresponding team. I found something on SO that works great for doing this - and it sorts teams by points in descending order (most to least).

There doesn't appear to be a sort on the second list.


EDIT - Original Data


Teams Pts
D Clark 0
D Dupuis 2
T Leach 2
J Schutz 0
C Hearder 2
R Pagani 0
M Cameron 2
B Hunter 0


This is what I'm using:

pts, teams = zip(*sorted(zip(pts, teams), reverse=True))
i = 1
for team, num_pts in zip(teams, pts):
standings = str(i) + '. ' + team + " (" + num_pts + ")"
print standings
i += 1


And it results in this:

1. T Leach (2)
2. M Cameron (2)
3. D Dupuis (2)
4. C Hearder (2)
5. R Pagani (0)
6. J Schutz (0)
7. D Clark (0)
8. B Hunter (0)


What I'm trying to do is to add an additional sort on team name - so if there's a tie, then it will sort by names in ascending order,

Like This:

1. C Hearder (2)
2. D Dupuis (2)
3. M Cameron (2)
4. T Leach (2)
5. B Hunter (0)
6. D Clark (0)
7. J Schutz (0)
8. R Pagani (0)

Answer

Define a custom cmp function that takes in two tuples as its argument, and compares according to your specification:

pts = ['2', '2', '2', '2', '2', '0', '0', '0', '0']
teams = ['T Leach', 'M Cameron', 'D Dupuis', 'C Hearder', 'R Pagani',
         'J Schutz', 'D Clark', 'B Hunter']

def custom_cmp(x,y):
    return cmp(x[0], y[0]) or cmp(y[1], x[1])

pts, teams = zip(*sorted(zip(pts, teams), cmp=custom_cmp, reverse=True))
i = 1
for team, num_pts in zip(teams, pts):
    standings = str(i) + '. ' + team + " ("  + num_pts + ")"
    print standings
    i += 1
Comments