【问题标题】:Python sort a list of dicts using a specified mappingPython 使用指定的映射对字典列表进行排序
【发布时间】: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 最初是无序的。在某些时候发生了更改,以便它们保持添加键的顺序。虽然对订单的控制很弱。如果要更改它,则需要创建一个新列表,按所需顺序添加键,或者您可以删除它们并从现有字典中重新添加它们。
  • 为什么不使用列表进行映射?
  • 你的映射是向后的...

标签: python list sorting dictionary mapping


【解决方案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'}]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2011-12-22
    • 2015-05-29
    • 1970-01-01
    相关资源
    最近更新 更多