繁体   English   中英

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

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

我有两个清单-一个代表球队名称,第二个代表积分

我想根据分数对它们进行排序,而又不会失去对相应团队的跟踪。 我在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)

您在这里有两个选择。 您可以使用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))

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

例如,如果您有一个元组列表(例如通过压缩两个列表),并且想要按第二项排序,那么第一项的键将是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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM