我有一份列表字典,summary
:
summary = {
'Raonic': [2, 0, 11, 122, 16, 139],
'Halep': [2, 2, 10, 75, 6, 60],
'Kerber': [2, 0, 7, 68, 7, 71],
'Wawrinka': [1, 2, 14, 133, 13, 128],
'Djokovic': [2, 2, 10, 75, 8, 125],
}
我希望按照排名的降序打印到屏幕(标准输出)的摘要,其中排名按照该顺序中的条件1-6(比较项目1(列表的)),如果相等比较项目2(列表中的),如果它们相等,则比较项目3(列表中的项目3)。此比较将以降序继续到列表的第4项。
但是,列表的第5项和第6项的比较必须以升序完成。
输出:
Halep 2 2 10 75 6 60
Djokovic 2 2 10 75 8 125
Raonic 2 0 11 122 16 139
Kerber 2 0 7 68 7 71
Wawrinka 1 2 14 133 13 128
我的解决方案是:
for key, value in sorted(summary.items(), key=lambda e: e[1][0], reverse = True):
print(key, end=' ')
for v in value:
print(v, end=' ')
print()
但是我的解决方案只是成功地对列表的第1列进行排序。
答案 0 :(得分:5)
对于数值,您可以否定该值以获得反向排序。对于您的排序键,返回一系列要排序的值,否定“对面”中的值。方向:
ranked = sorted(
summary.items(),
key=lambda kv: kv[1][:4] + [-kv[1][4], -kv[1][5]],
reverse=True)
这会按排序顺序生成(key, value)
个元组,因为字典是无序的。
对于('Halep', [2, 2, 10, 75, 6, 60])
,排序键lambda返回[2, 2, 10, 75, -6, -60]
,确保在 'Djokovic'
之前将其排序,其中排序键设置为{{1} },因为在反向排序顺序([2, 2, 10, 75, -8, -125]
)中,reverse=True
在-6
之前排序。但是,前4列中任何值的差异都按另一个方向排序,因此第一列中-8
或更多的任何内容都将在3
之前排序,或以{{1}开头的任何内容排序或更高等等。
如果值不是数字,并且没有其他的反转'列可用的值选项,您必须对两次进行排序。首先是最后2列(按升序排序),然后是前4列(按降序排列,反之,顺序排列):
('Halep', [...])
这是因为Python的排序算法(称为Timsort)是 stable ,排序键完全相等的任何两个输入的相对顺序是不受影响的。因此,任何键 A 和 B ,其中只有最后一列或两列不同,在2, 3
中给出相对排序,然后不会改变在# non-numeric option
part_sorted = sorted(summary.items(), key=lambda kv: kv[1][-2:])
ranked = sorted(part_sorted, key=lambda kv: kv[1][:4], reverse=True)
中,因为part_sorted
订单未受影响。如果 A 在第一个排序中的 B 之后排序,那么第二个排序将在 B 之后留下 A 。