Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据匹配值合并两个词典列表,否则保留原始值?_Python_List_Dictionary_Match - Fatal编程技术网

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解决方案也会起作用,但除非遇到性能问题,否则我不会这样做。谢谢你们两位!