Python中合并含相同firstname和lastname的多组字典列表
字典列表合并问题
需求说明
需要合并三组字典列表,每组字典包含姓名相关键(注意大小写不一致:列表一用First Name,其他列表用firstName,但都有lastName)。合并规则:
- 按**
firstName/First Name+lastName完全匹配**识别同一个人 - 每个姓名仅保留一组标准的
firstName和lastName - 合并其余所有字段,重复字段以最后出现的列表(列表三→列表二→列表一)的数值为准
列表一
[{'First Name': 'Justin', 'lastName': 'Walker', 'Age (Years)': '29', 'Sex': 'Male', 'Vehicle Make': 'Toyota', 'Vehicle Model': 'Continental', 'Vehicle Year': '2012', 'Vehicle Type': 'Sedan'}, {'First Name': 'Maria', 'lastName': 'Jones', 'Age (Years)': '66', 'Sex': 'Female', 'Vehicle Make': 'Mitsubishi', 'Vehicle Model': 'Yukon XL 2500', 'Vehicle Year': '2014', 'Vehicle Type': 'Van/Minivan'}, {'First Name': 'Samantha', 'lastName': 'Norman', 'Age (Years)': '19', 'Sex': 'Female', 'Vehicle Make': 'Aston Martin', 'Vehicle Model': 'Silverado 3500 HD Regular Cab', 'Vehicle Year': '1995', 'Vehicle Type': 'SUV'}]
列表二
[{'firstName': 'Justin', 'lastName': 'Walker', 'age': 71, 'iban': 'GB43YKET96816855547287', 'credit_card_number': '2221597849919620', 'credit_card_security_code': '646', 'credit_card_start_date': '03/18', 'credit_card_end_date': '06/26', 'address_main': '462 Marilyn radial', 'address_city': 'Lynneton', 'address_postcode': 'W4 0GW'}, {'firstName': 'Maria', 'lastName': 'Jones', 'age': 91, 'iban': 'GB53QKRK45175204753504', 'credit_card_number': '4050437758955103343', 'credit_card_security_code': '827', 'credit_card_start_date': '11/21', 'credit_card_end_date': '01/27', 'address_main': '366 Brenda radial', 'address_city': 'Ritafurt', 'address_postcode': 'NE85 1RG'}]
列表三
[{'firstName': 'Justin', 'lastName': 'Walker', 'age': '64', 'sex': 'Male', 'retired': 'False', 'dependants': '2', 'marital_status': 'single', 'salary': '56185', 'pension': '0', 'company': 'Hudson PLC', 'commute_distance': '14.1', 'address_postcode': 'G2J 0FH'}, {'firstName': 'Maria', 'lastName': 'Jones', 'age': '69', 'sex': 'Female', 'retired': 'False', 'dependants': '1', 'marital_status': 'divorced', 'salary': '36872', 'pension': '0', 'company': 'Wall, Reed and Whitehouse', 'commute_distance': '10.47', 'address_postcode': 'TD95 7FL'}]
尝试的代码
for i in range(0,2): dict1 = list_one[i] dict2 = list_two[i] dict3 = list_three[i] combine_file = list_three.copy() for k, v in dict1.items(): if k == "firstname" or "lastname": for k1, v1 in combine_file.items(): if dict1.get(k) == combine_file.v1:
预期输出
[{'firstName': 'Justin', 'lastName': 'Walker', 'age': '64', 'sex': 'Male', 'retired': 'False', 'dependants': '2', 'marital_status': 'single', 'salary': '56185', 'pension': '0', 'company': 'Hudson PLC', 'commute_distance': '14.1', 'iban': 'GB43YKET96816855547287', 'credit_card_number': '2221597849919620', 'credit_card_security_code': '646', 'credit_card_start_date': '03/18', 'credit_card_end_date': '06/26', 'address_main': '462 Marilyn radial', 'address_city': 'Lynneton', 'address_postcode': 'W4 0GW', 'Vehicle Make': 'Toyota', 'Vehicle Model': 'Continental', 'Vehicle Year': '2012', 'Vehicle Type': 'Sedan'}, {'firstName': 'Maria', 'lastName': 'Jones', 'age': '69', 'sex': 'Female', 'retired': 'False', 'dependants': '1', 'marital_status': 'divorced', 'salary': '36872', 'pension': '0', 'company': 'Wall, Reed and Whitehouse', 'commute_distance': '10.47', 'iban': 'GB53QKRK45175204753504', 'credit_card_number': '4050437758955103343', 'credit_card_security_code': '827', 'credit_card_start_date': '11/21', 'credit_card_end_date': '01/27', 'address_main': '366 Brenda radial', 'address_city': 'Ritafurt', 'address_postcode': 'NE85 1RG', 'Vehicle Make': 'Mitsubishi', 'Vehicle Model': 'Yukon XL 2500', 'Vehicle Year': '2014', 'Vehicle Type': 'Van/Minivan'}]
解决方案
思路
- 统一姓名字段格式:把列表一的
First Name改成firstName,确保所有字典用相同的键标识姓名,避免大小写导致匹配失败。 - 用字典做临时容器:以
(firstName, lastName)作为唯一标识,遍历三个列表,把字段逐步合并进去——后遍历的列表字段会覆盖前面的重复字段,刚好符合预期的优先级。 - 过滤结果:只保留在三个列表中都有数据的条目(比如Samantha只有列表一的数据,故排除)。
代码实现
# 定义原始列表 list_one = [{'First Name': 'Justin', 'lastName': 'Walker', 'Age (Years)': '29', 'Sex': 'Male', 'Vehicle Make': 'Toyota', 'Vehicle Model': 'Continental', 'Vehicle Year': '2012', 'Vehicle Type': 'Sedan'}, {'First Name': 'Maria', 'lastName': 'Jones', 'Age (Years)': '66', 'Sex': 'Female', 'Vehicle Make': 'Mitsubishi', 'Vehicle Model': 'Yukon XL 2500', 'Vehicle Year': '2014', 'Vehicle Type': 'Van/Minivan'}, {'First Name': 'Samantha', 'lastName': 'Norman', 'Age (Years)': '19', 'Sex': 'Female', 'Vehicle Make': 'Aston Martin', 'Vehicle Model': 'Silverado 3500 HD Regular Cab', 'Vehicle Year': '1995', 'Vehicle Type': 'SUV'}] list_two = [{'firstName': 'Justin', 'lastName': 'Walker', 'age': 71, 'iban': 'GB43YKET96816855547287', 'credit_card_number': '2221597849919620', 'credit_card_security_code': '646', 'credit_card_start_date': '03/18', 'credit_card_end_date': '06/26', 'address_main': '462 Marilyn radial', 'address_city': 'Lynneton', 'address_postcode': 'W4 0GW'}, {'firstName': 'Maria', 'lastName': 'Jones', 'age': 91, 'iban': 'GB53QKRK45175204753504', 'credit_card_number': '4050437758955103343', 'credit_card_security_code': '827', 'credit_card_start_date': '11/21', 'credit_card_end_date': '01/27', 'address_main': '366 Brenda radial', 'address_city': 'Ritafurt', 'address_postcode': 'NE85 1RG'}] list_three = [{'firstName': 'Justin', 'lastName': 'Walker', 'age': '64', 'sex': 'Male', 'retired': 'False', 'dependants': '2', 'marital_status': 'single', 'salary': '56185', 'pension': '0', 'company': 'Hudson PLC', 'commute_distance': '14.1', 'address_postcode': 'G2J 0FH'}, {'firstName': 'Maria', 'lastName': 'Jones', 'age': '69', 'sex': 'Female', 'retired': 'False', 'dependants': '1', 'marital_status': 'divorced', 'salary': '36872', 'pension': '0', 'company': 'Wall, Reed and Whitehouse', 'commute_distance': '10.47', 'address_postcode': 'TD95 7FL'}] # 初始化合并容器 merged = {} # 处理列表一:统一姓名字段格式 for item in list_one: temp = item.copy() # 把First Name转为firstName if 'First Name' in temp: temp['firstName'] = temp.pop('First Name') # 用姓名元组当唯一键 key = (temp['firstName'], temp['lastName']) merged[key] = temp # 处理列表二:合并字段,重复字段覆盖 for item in list_two: key = (item['firstName'], item['lastName']) if key in merged: merged[key].update(item) else: merged[key] = item # 处理列表三:最后处理,覆盖之前的重复字段 for item in list_three: key = (item['firstName'], item['lastName']) if key in merged: merged[key].update(item) else: merged[key] = item # 过滤出有三组数据的条目(排除只有列表一数据的Samantha) result = [v for v in merged.values() if len(v) > len(list_one[0])] # 打印结果 import pprint pprint.pprint(result)
代码说明
- 统一姓名字段:解决不同列表中姓名字段大小写不一致的问题,保证同一个人能被正确识别。
- 合并逻辑:利用字典的
update方法,后面的字段会直接覆盖前面的重复字段,刚好满足预期输出的优先级要求。 - 结果过滤:通过字段数量判断是否在三个列表中都有数据,也可以直接指定需要保留的姓名,按需调整即可。
内容的提问来源于stack exchange,提问作者princewill
相关产品推荐
相关产品推荐

