在python中对并行列表进行排序 - 第一项降序,第二项升序

时间:2016-10-09 03:45:03

标签: python list python-2.7 sorting

我有两个列表 - 一个用于团队名称,第二个用于点

我想根据这些点对它们进行排序,而不会失去对相应团队的跟踪。我在SO上发现了一些非常适合这样做的东西 - 它按照降序(最多到最少)对点进行排序。

在第二个列表中似乎没有排序。

  

编辑 - 原始数据

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

这就是我正在使用的内容:

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

结果如下:

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)

我尝试做的是在团队名称上添加一个额外的排序 - 所以如果有一个平局,那么按名称按升序顺序排序,

喜欢这个:

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)

2 个答案:

答案 0 :(得分:1)

这里有两种选择。您可以使用cmpkey作为sorted的参数。

使用cmp,您定义了一个带有两个参数的函数,这两个值被比较。如果第一个参数小于第二个参数,则返回负数。如果它大于第二个,则返回正数。如果它们相等,则返回0.

使用cmp的第一个示例:

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))

如果python or运算符如上所述评估为True(而不是0),则它将返回左侧,否则它将返回右侧。因此,如果点数不相等,则此custom_cmp会返回xy之间的点数比较。否则,它会将yx的小组进行比较(相反的顺序)。

另一方面,使用key,您只是考虑如何单独查看元素,以便python自然地理解如何按照您想要的方式对其进行排序。我们知道第一项正在进行比较,所以现在我们只需要翻转第二项。数字很​​容易,我们可以采取负面的。但你怎么翻弦呢?

一种方法是对字符串中的每个字符取ord(应该是字符串的ascii值整数)。然后,您可以对这些值进行否定,并将它们打包成tuple。这就是其中一个看起来像:

>>> tuple(-ord(c) for c in 'C Hearder')
(-67, -32, -72, -101, -97, -114, -100, -101, -114)

使用key的第二个例子:

def custom_key(pair):
    pts, team = pair
    return (pts, tuple(-ord(c) for c in team))

pts, teams = zip(*sorted(zip(pts, teams), key=custom_key, reverse=True))

回顾编辑:

如果我们要定义自定义key,我们也可以反转key本身并删除reverse参数:

def custom_key(pair):
    pts, team = pair
    return (-int(pts), team)

pts, teams = zip(*sorted(zip(pts, teams), key=custom_key))

答案 1 :(得分:1)

您可以通过传递sorted kwarg来指定key的排序方式。使用key的一种方便方法是使用itemgetter模块中的operator

例如,如果您有一个元组列表(例如通过压缩两个列表)并且您希望按第二个项排序,那么第一个项,键将是itemgetter(1,0)所以您可能会执行类似的操作这样:

from operator import itemgetter
teams_and_points = zip(teams, pts)
for team, points in sorted(points_and_teams, key=itemgetter(1, 0)):
    print(team, points)