Python 根据匹配值合并两个词典列表,否则保留原始值?
是否可以循环遍历字典的结果列表,然后查找是否有匹配的树,并从附加高度的结果输出字典?如果没有匹配项,我还希望将字典包含在原始格式中。因此,此场景中的输出将是字典的组合列表 期望输出:Python 根据匹配值合并两个词典列表,否则保留原始值?,python,list,dictionary,match,Python,List,Dictionary,Match,是否可以循环遍历字典的结果列表,然后查找是否有匹配的树,并从附加高度的结果输出字典?如果没有匹配项,我还希望将字典包含在原始格式中。因此,此场景中的输出将是字典的组合列表 期望输出: combined = [ {'Type':'Tree', 'Name':'Pear', 'Color':'Red,Green', 'Height':'25ft'}, {'Type':'Bush', 'Name':'Raspberry', 'Color':'Red,White'}, {'Typ
combined = [
{'Type':'Tree', 'Name':'Pear', 'Color':'Red,Green', 'Height':'25ft'},
{'Type':'Bush', 'Name':'Raspberry', 'Color':'Red,White'},
{'Type':'Tree', 'Name':'Apple', 'Color':'Red,Green', 'Height':'15ft'}
]
起始表格:
fruit = [
{'Type':'Tree', 'Name':'Pear', 'Color':'Red,Green'},
{'Type':'Bush', 'Name':'Raspberry', 'Color':'Red,White'},
{'Type':'Tree', 'Name':'Apple', 'Color':'Red,Green'}
]
type = [
{'Type':'Tree', 'Fruit':'Pear', 'Height':'25ft'},
{'Type':'Tree', 'Fruit':'Apple', 'Height':'15ft'},
{'Type':'Root', 'Fruit':'Carrot', 'Height':'2ft'}
]
当我尝试这样做的时候,当使用下面的代码时,我会不断得到重复的输出。我想这是因为嵌套循环,但我不确定
combined = []
for i in fruit:
for x in type:
if i['Name'] == x['Name']:
out = i
out['Height'] = x['Height']
combined.append(out)
else:
combined.append(i)
这是避免嵌套
for
循环的一种方法
设置
fruit = [{'Type':'Tree', 'Name':'Pear', 'Color':'Red,Green'},
{'Type':'Bush', 'Name':'Raspberry', 'Color':'Red,White'},
{'Type':'Tree', 'Name':'Apple', 'Color':'Red,Green'}]
tree_types = [{'Type':'Tree', 'Fruit':'Pear', 'Height':'25ft'},
{'Type':'Tree', 'Fruit':'Apple', 'Height':'15ft'},
{'Type':'Root', 'Fruit':'Carrot', 'Height':'2ft'}]
注意:不要在内置后命名变量,例如类型
解决方案
tree_types_d = {(i['Type'], i['Fruit']): i['Height'] for i in tree_types}
for item in fruit:
tup = (item['Type'], item['Name'])
if tup in tree_types_d:
item['Height'] = tree_types_d[tup]
结果
[{'Color': 'Red,Green', 'Height': '25ft', 'Name': 'Pear', 'Type': 'Tree'},
{'Color': 'Red,White', 'Name': 'Raspberry', 'Type': 'Bush'},
{'Color': 'Red,Green', 'Height': '15ft', 'Name': 'Apple', 'Type': 'Tree'}]
解释
tree_types_d = {(i['Type'], i['Fruit']): i['Height'] for i in tree_types}
for item in fruit:
tup = (item['Type'], item['Name'])
if tup in tree_types_d:
item['Height'] = tree_types_d[tup]
- 将
重组为元组字典,树类型
树类型
- 迭代
并在与水果
匹配的地方添加树类型
项高度
- 构建新字典的一次性成本通常比嵌套的
循环更可取for
- 问题在于内部循环中的if-else语句
您应该设置一个标志来检查内部循环中是否有匹配项,如果没有匹配项,则应将当前水果添加到内部循环之外
combined = []
for i in fruit:
found = False
for x in type:
if i['Name'] == x['Fruit']:
out = []
out = i
out['Height'] = x['Height']
combined.append(out)
found = True
if found == False:
combined.append(i)
如果您使用的是Python 3.5+,请使用您定义的
fruit
和tree\u type
变量(type
重命名为tree\u type
,以避免冲突):
对该代码的一些解释:
表达式next((type_dict for type_dict in tree_dict in tree_type if fruit_dict[“Name”]==type_dict[“fruit”]),{})
在tree_type
中找到一个匹配fruit_dict
并返回它,否则返回一个空dict{/code>
表达式{**d1,**d2}
用于合并这两个词典。此表达式中没有任何词典被更改,将返回一个新词典
当tree\u type
是一个大列表时,此代码未优化。如果是这样的话,您应该在不同的数据结构(可能是字典)中组织此列表
例如:
tree_types_by_fruit = {type_dict["Fruit"]: type_dict for type_dict in tree_type}
combined = [{**fruit_dict, **tree_types_by_fruit.get(fruit_dict["Name"], {})} for fruit_dict in fruit]
它不能扩展到更大的
树型。对于大的水果,这是可以的。除了我已经吃过的水果之外,这是一种又好又容易的添加。我不知道为什么我没有想到。。。我认为@jpp解决方案也会起作用,但除非遇到性能问题,否则我不会这样做。谢谢你们两位!