Python - 记录将一个词典列表更新到另一个词典列表所需的更改

Python - Log the changes needed for one list of dictionaries to be updated to another

我有两个很大的词典列表:

list1 = [{name: "John", age: 25}, {name: "Sarah", age: 31}, {name: "Frank", age: 12}]
list2 = [{name: "John", age: 25}, {name: "Sarah", age: 32}, {name: "Dave", age: 13}]

想法是记录将 list1 更新为 list2 所需的更改。

add = []          
remove = []      
age_diff = []    

add 包含在 list2 中唯一的任何人的名字,应该添加到 list1

remove 包含 list1 应删除的任何人的唯一名称

age_diff 包含年龄在 list1list2

之间变化的任何人的姓名

我就是这样做的:

for item1 in list1:
    if any(item2["name"] == item1["name"] for item2 in list2):
        # if item1["age"] != item2["age"]:                         # won't work as item2
            # age_diff.append(item1["name"])                       # can't be accessed. 
    else:
        add.append(item1["name"])

for item2 in list2:
    if any(item1["name"] == item2["name"] for item1 in list1):
        pass
    else:
        remove.append(item2["name"])

嵌套的 for i in range() 循环可以让我对 age 进行比较,但感觉不是很 pythonic。我希望对列表使用 set() 比较,而不是将结果附加到新列表,但我不认为有一种方法可以满足我的目的。

已编辑以包含示例

在你的第一个循环中,不要只用 any 测试条件,将等效的 item2 设置为一个变量,这样你就可以用它来比较 if 语句中的年龄。所以我会改变:

if any(item2["name"] == item1["name"] for item2 in list2):

至:

item2 = [x for x in list2 if x["name"] == item1["name"]]

item2 现在按名称保存匹配项列表。假设这总是 0 或 1 个项目,您可以像这样继续测试 item2[0](如您的评论中所示):

if item2:
    if item1["age"] != item2[0]["age"]:
        age_diff.append(item1["name"])
else:
    add.append(item1["name"])