如何使用另一个字典列表更新字典列表?

3
我有两个列表,如下所示。我想使用旧列表更新新列表。更新新列表的标准是在旧列表中匹配name的值。最好的方法是什么? 输入
old_list = [{'age': 35, 'name': 'james'}, {'age': 42, 'name': 'bob'}]

new_list = [{'name': 'peter'}, {'name': 'james'}, {'age': 50, 'name': 'bob'}]

预期输出
[{'name': 'peter'}, {'age': 35, 'name': 'james'}, {'age': 42, 'name': 'bob'}]

编辑:添加我的解决方案

我知道一种解决此问题的方法,需要使用多个循环和if条件语句。这不是完整的解决方案,因为我还需要处理多种情况,例如键不存在等。

for x in new_col_list:
    for y in old_col_list:
        if x['name'] == y['name']:
            x['age'] = y['age']
            continue

print new_col_list

你想让 'Bob' 的年龄保持在42岁还是更新为50岁? - Rittel
我想从旧列表中取值。因此在这种情况下,我希望将50更新为42。 - conetfun
1
你有尝试解决这个问题吗?它看起来相当简单。 - Mad Physicist
顺序重要吗? - Mad Physicist
让我们在聊天室里继续这个讨论 - conetfun
显示剩余4条评论
1个回答

5

您需要一个结构,可以让您从一个列表中查找另一个列表中的项目。字典提供了这样的结构:

lookup = {x['name']: x for x in new_list}
lookup.update({x['name']: x for x in old_list})

如果你真的想要,你可以将其转换回列表:
result = list(lookup.values())

在Python 3.6及以上版本中,新列表的顺序将是所有元素,接着是按照旧列表中的顺序添加的所有缺失元素。对于较早版本的Python,可以通过使用collections.OrderedDict来实现相同的效果。
lookup = OrderedDict((x['name'], x) for x in new_list)
lookup.update((x['name'], x) for x in old_list)

没有排序,dict.values() 的结果将是任意顺序的,并且可能在解释器的不同运行之间发生更改。
附录
每当您看到一个字典推导式时,它在功能上等同于一个 for 循环。这里是第一个建议代码的“展开”版本:
lookup = {}
for d in new_list:
    lookup[d['name']] = d
for d in old_list:
    lookup[d['name']] = d

实际上,我来自 SQL 背景,对编程的知识非常有限(if else、循环等),因此很难理解这种语法 - {x['name']: x for x in new_list}。我看到第一行使用 new_list 创建了一个字典,第二行使用旧字典更新了这个新创建的字典。乍一看,这个语法看起来非常难以理解,因为我总是试图通过循环、if else 条件来解决问题。 - conetfun
那个语法不是解决问题所必需的。虽然比写完整的 for 循环更快、更整洁,但它确实按照你思考的方式来进行。 - Mad Physicist
谢谢。我刚刚覆盖了我写的代码,但让我重新编写并分享它。不知怎么的,我感觉我之前做的不是解决这个问题的好方法。我需要10分钟来分享我的解决方案。 - conetfun
我已经添加了我的代码,试图解决这个问题。但是在其中有多种情况需要处理,以使其更加完善。 - conetfun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接