首页 > 解决方案 > 更新的字典列表

问题描述

我有一个字典列表。

my_list = [
    {"id": "UU7t", "updated_at": "2020-01-06_16-40-00", "summary": "Renewed"},
    {"id": "yT8h", "updated_at": "2020-01-07_18-24-22", "summary": "Renewed"},
    {"id": "i8Po", "updated_at": "2020-01-08_13-16-36", "summary": "Renewed"},
    {"id": "yT8h", "updated_at": "2020-01-13_18-24-05", "summary": "Deleted"},
    {"id": "7uYg", "updated_at": "2020-01-18_23-37-19", "summary": "Transferred"},
]

我想获取删除重复字典的列表,其中 id 相同但“updated_at”是最新的。

所以,我的最终名单将是:

my_list = [
    {"id": "UU7t", "updated_at": "2020-01-06_16-40-00", "summary": "Renewed"},
    {"id": "i8Po", "updated_at": "2020-01-08_13-16-36", "summary": "Renewed"},
    {"id": "yT8h", "updated_at": "2020-01-13_18-24-05", "summary": "Deleted"},
    {"id": "7uYg", "updated_at": "2020-01-18_23-37-19", "summary": "Transferred"},
]

什么是有效的方法?

标签: pythonpython-3.xlistdictionary

解决方案


您可以使用 adict来累积项目。

字典可以存储idas 键和列表项作为值。如果不存在具有相同键的项,则仅在字典中插入一项;如果它确实比较updated_at值并在需要时更新字典。

def generate_new_list(my_list):
    counts = {}
    for d in my_list:
        item_id = d['id']
        if item_id in counts:
            if d['updated_at'] > counts[item_id]['updated_at']:
                counts[item_id] = d
        else:
            counts[item_id] = d

    return list(counts.values())

还有一些注意事项:

  • 如果您想保留原始顺序,请确保您使用的是 Python 3.7(它保证 dicts 按插入顺序排序)或使用 OrderedDict。使用标准 dict,您必须首先弹出条目,因为替换不会更改 dict 顺序(因此每个项目都将按照其 id 首次出现的顺序输出),而 ordereddict 对该用例有特殊支持(move_to_end) .
  • 您还可以通过使用dict.get和“空对象模式”删除特殊情况:

    MISSING = {'updated_at': '0'} # pseudo-entry smaller than all possible
    def generate_new_list(my_list):
        counts = {}
        for d in my_list:
            if d['updated_at'] > counts.get(d['id'], MISSING):
                counts[d['id']] = d
    
        return list(counts.values())
    
  • 一种非字典替代方案(尽管非常保存顺序)是按(id,updated_by)排序,按id分组,然后只保留最后一个条目。我不认为 stdlib 提供了开箱即用的最后一个操作(islice 不接受负索引),因此您要么必须手动执行此操作,要么首先将子条目具体化为列表。

推荐阅读