【问题标题】:Intersection of two list of dictionaries based on a key基于键的两个字典列表的交集
【发布时间】:2023-03-25 16:45:02
【问题描述】:

我有两个不同的字典列表,

list1 = [{'count': 351, 'att_value': 'one'},
         {'count': 332,  'att_value': 'two'},
         {'count': 336,  'att_value': 'six'},
         {'count': 359,  'att_value': 'nine'},
         {'count': 304,  'att_value': 'four'}]

list2 = [{'count': 359,'person_id' : 4},
         {'count': 351, 'person_id' : 12},
         {'count': 381, 'person_id' : 8}]

如何通过像 list_C 一样包含键的其余部分,基于“count”键找到 list_A 与 list_B 的交集?

list3 = [{'count':359, 'att_value' : 'nine', 'person_id':4},
         {'count':351, 'att_value' : 'one', 'person_id':12},
         {'count':381, 'att_value' : '-', 'person_id':8}] 

我想保留 list2 中的键,但 list1 中的缺失值用“-”表示。

【问题讨论】:

    标签: python python-3.x list dictionary


    【解决方案1】:

    您也可以为此使用pandas 库:

    In [102]: df1 = pd.DataFrame(list1)
    In [104]: df2 = pd.DataFrame(list2)
    
    In [106]: pd.merge(df2,df1, on='count', how='left').fillna('-')
    Out[106]: 
         count att_value
    0    359      nine
    1    351       one
    2    381         -
    

    【讨论】:

    • 完成。删除它。
    【解决方案2】:

    您可以通过列表推导来做到这一点。首先,从list2 构建一个所有计数的集合,然后根据常数时间集合成员检查过滤掉字典。

    counts = {d2['count'] for d2 in list2}
    list3 = [d for d in list1 if d['count'] in counts]
    
    print(list3)
    # [{'count': 351, 'att_value': 'one', 'person_id': 12}, 
    #  {'count': 359, 'att_value': 'nine', 'person_id': 4}]
    

    (Re:Edit)要适当地处理其他键(除了“att_value”),以同样的方式给出默认值'-',您可以使用:

    keys = list1[0].keys() - {'count'}
    idx = {d['count'] : d for d in list1}
    list3 = []
    for d in list2:
        d2 = idx.get(d['count'], dict.fromkeys(keys, '-'))
        d2.update(d)
        list3.append(d2)
    
    print(list3)
    # [{'count': 359, 'att_value': 'nine', 'person_id': 4},
    #  {'count': 351, 'att_value': 'one', 'person_id': 12},
    #  {'person_id': 8, 'att_value': '-', 'count': 381}]
    

    【讨论】:

      【解决方案3】:

      假设list1 中的字典共享相同的键并且您拥有 Python 3.5 或更高版本,您可以编写以下列表解析。

      >>> count2dict = {d['count']:d for d in list1}                                                                                                                  
      >>> dummies = dict.fromkeys(list1[0], '-')                                                                                                                      
      >>> [{**count2dict.get(d['count'], dummies), **d} for d in list2]                                                                                              
      [{'count': 359, 'att_value': 'nine', 'person_id': 4},
       {'count': 351, 'att_value': 'one', 'person_id': 12},
       {'count': 381, 'att_value': '-', 'person_id': 8}]
      

      【讨论】:

        【解决方案4】:

        使用更详细的for 循环,更新list2 的对象:

        for item2 in list2:
          item2['att_value'] = '-'
          item1 = [ item1 for item1 in list1 if item1['count'] == item2['count'] ]
          if item1: item2.update(item1[0])
        
        print(list2)
        #=> [{'count': 359, 'person_id': 4, 'att_value': 'nine'}, {'count': 351, 'person_id': 12, 'att_value': 'one'}, {'count': 381, 'person_id': 8, 'att_value': '-'}]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-03
          • 2021-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-24
          相关资源
          最近更新 更多