按多个键对字典排序列表,包括列表

时间:2019-04-04 23:20:04

标签: python sorting

我想按列表键然后按日期对字典列表进行排序。 我正在尝试根据label_order按“标签”对字典进行排序,然后对“日期”进行降序。

label_order = [3, 4, 2, 1]

data = [
    {'label': 1, 'data': 5, 'date': datetime(2018, 12, 31)},
    {'label': 3, 'data': 2, 'date': datetime(2017, 12, 31)},
    {'label': 3, 'data': 1, 'date': datetime(2018, 12, 31)},
    {'label': 4, 'data': 3, 'date': datetime(2018, 12, 31)},
    {'label': 4, 'data': 4, 'date': datetime(2018, 12, 25)},
]

排序后将如下所示:

data = [
    {'label': 3, 'data': 1, 'date': datetime(2018, 12, 31)},
    {'label': 3, 'data': 2, 'date': datetime(2017, 12, 31)},
    {'label': 4, 'data': 3, 'date': datetime(2018, 12, 31)},
    {'label': 4, 'data': 4, 'date': datetime(2018, 12, 25)},
    {'label': 1, 'data': 5, 'date': datetime(2018, 12, 31)},
]

我尝试了lambda表达式和itemgetter,但是我很难为sort键组合正确的策略。也许只是一次尝试做太多事情。

任何帮助或指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

一种更有效的方法是构建一个字典,将label_order中的项目映射到索引,以便在执行排序时可以将索引用作键:

keys = {n: i for i, n in enumerate(label_order)}
sorted(data, key=lambda d: (-keys[d['label']], d['date']), reverse=True)

这将返回:

[{'label': 3, 'data': 1, 'date': datetime(2018, 12, 31)},
 {'label': 3, 'data': 2, 'date': datetime(2017, 12, 31)},
 {'label': 4, 'data': 3, 'date': datetime(2018, 12, 31)},
 {'label': 4, 'data': 4, 'date': datetime(2018, 12, 25)},
 {'label': 1, 'data': 5, 'date': datetime(2018, 12, 31)}]

答案 1 :(得分:1)

以相反的顺序对日期进行排序有点棘手。取而代之的是,我们使用标签索引的负值,以便它们按降序排序。然后,我们可以反转排序并按我们想要的顺序获得结果!

from datetime import datetime

label_order = [3, 4, 2, 1]

data = [
    {'label': 1, 'data': 5, 'date': datetime(2018, 12, 31)},
    {'label': 3, 'data': 2, 'date': datetime(2017, 12, 31)},
    {'label': 3, 'data': 1, 'date': datetime(2018, 12, 31)},
    {'label': 4, 'data': 3, 'date': datetime(2018, 12, 31)},
    {'label': 4, 'data': 4, 'date': datetime(2018, 12, 25)},
]

def descending_sort_key(item):
    return -label_order.index(item['label']), item['date']

data.sort(key=descending_sort_key, reverse=True)

Voila-没有日期数学或其他技巧。