Python 使用指定的映射对字典列表进行排序

Posted

技术标签:

【中文标题】Python 使用指定的映射对字典列表进行排序【英文标题】:Python sort a list of dicts using a specified mapping 【发布时间】:2021-11-15 16:30:00 【问题描述】:

所以,我有一个 Python 中的字典列表,如下所示:

lis =
[
'action': 'Notify', 'type': 'Something', 'Genre': 10, 'date': '2021-05-07 01:59:37',
'action': 'Notify', 'type': 'Something Else', 'Genre': 20, 'date': '2021-05-07 01:59:37'
...
]

现在我希望lis 以某种方式使用,以便每个单独的字典 使用mapping 对我将提供的键进行排序。例如,如果

mapping = 1:'date', 2:'Genre', 3:'action', 4:'type'

然后,我想让我的原始字典列表如下所示:

lis =
[
'date': '2021-05-07 01:59:37', 'Genre': 10, 'action': 'Notify', 'type': 'Something',
'date': '2021-05-07 01:59:37', 'Genre': 20, 'action': 'Notify', 'type': 'Something Else'
...
]

我该如何实现?

【问题讨论】:

所以你想自定义排序你的字典? 是的,没错。 Python dicts 最初是无序的。在某些时候发生了更改,以便它们保持添加键的顺序。虽然对订单的控制很弱。如果要更改它,则需要创建一个新列表,按所需顺序添加键,或者您可以删除它们并从现有字典中重新添加它们。 为什么不使用列表进行映射? 你的映射是向后的... 【参考方案1】:

您可以使用collections.OrderedDict 来完成此任务,如下所示

import collections
order = ['date', 'Genre', 'action', 'type']
dct1 = 'action': 'Notify', 'type': 'Something', 'Genre': 10, 'date': '2021-05-07 01:59:37'
dct2 = 'action': 'Notify', 'type': 'Something Else', 'Genre': 20, 'date': '2021-05-07 01:59:37'
odct1 = collections.OrderedDict.fromkeys(order)
odct1.update(dct1)
odct2 = collections.OrderedDict.fromkeys(order)
odct2.update(dct2)
print(odct1)
print(odct2)

输出:

OrderedDict([('date', '2021-05-07 01:59:37'), ('Genre', 10), ('action', 'Notify'), ('type', 'Something')])
OrderedDict([('date', '2021-05-07 01:59:37'), ('Genre', 20), ('action', 'Notify'), ('type', 'Something Else')])

免责声明:假设您要处理的每个字典都具有来自order 的所有键。此解决方案适用于任何具有collections.OrderedDict 的python 版本,如果您将仅使用python3.7 或更新的版本,您可以使用常见的dict,如下所示

order = ['date', 'Genre', 'action', 'type']
dct1 = dict.fromkeys(order)
dct1.update('action': 'Notify', 'type': 'Something', 'Genre': 10, 'date': '2021-05-07 01:59:37')
print(dct1)

输出

'date': '2021-05-07 01:59:37', 'Genre': 10, 'action': 'Notify', 'type': 'Something'

免责声明仍然有效

【讨论】:

OrderedDict 在较新版本的 Python 中不是必需的【参考方案2】:

使用列表理解:

lis = [
'action': 'Notify', 'type': 'Something', 'Genre': 10, 'date': '2021-05-07 01:59:37',
'action': 'Notify', 'type': 'Something Else', 'Genre': 20, 'date': '2021-05-07 01:59:37'
]

mapping = 1:'date', 2:'Genre', 3:'action', 4:'type'

sorted_lis = [
    field: record[field] for field in mapping.values()
    for record in lis
]

print(sorted_lis)

【讨论】:

谢谢,这以优雅的方式解决了我的目的,无需导入。在性能方面有什么缺点吗? @DebapratimChakraborty 这个,我不能说,对不起。 OrderedDict 可能更快。尽管如此,我还是尝试对 10^6 元素列表(列表中的项目重复)进行列表理解,它在 1.25 秒内终止,所以看起来相当快。【参考方案3】:

试试这个:

def sort_dct(li, mapping):
    return v: li[v] for k,v in mapping.items()

out = []
mapping = 1:'date', 2:'Genre', 3:'action', 4:'type'
for li in lis:
    out.append(sort_dct(li,mapping))
    
print(out)

输出:

['date': '2021-05-07 01:59:37',
  'Genre': 10,
  'action': 'Notify',
  'type': 'Something',
 'date': '2021-05-07 01:59:37',
  'Genre': 20,
  'action': 'Notify',
  'type': 'Something Else']

【讨论】:

以上是关于Python 使用指定的映射对字典列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

python 字典排序

如何一次对字典或列表中的所有嵌套字典和列表进行排序?

python按自定义顺序排序字典列表[重复]

在python中按日期时间对字典列表进行排序

在Python列表中对嵌套字典进行排序? [复制]

如何在 Python 中对字典列表进行多重排序? [复制]