【问题标题】:Python - Join two lists of dictionaries on a contains, and leave out any that do not match?Python - 加入包含的两个字典列表,并忽略任何不匹配的?
【发布时间】:2019-12-12 20:03:43
【问题描述】:

我正在尝试加入两个字典列表,其中一个字段包含另一个字段的一部分,如果没有匹配项则将其删除。

list_1 = [{
    "bytes_in": 0,
    "rsrq": -50,
    "hostname": "AB9472"
},
{
    "bytes_in": 0,
    "rsrq": -90,
    "hostname": "DF4845"
},
{
    "bytes_in": 0,
    "rsrq": "None",
    "hostname": "FC4848"
}
]

list_2 = [{
    "id": 249,
    "ref_no": "AB9472 - 015632584",
    "rssi": "-75.0",
    "circuit_type": "4G"
},
{
    "id": 17,
    "ref_no": "DF4845 - 8984494",
    "rssi": "-20.0",
    "circuit_type": "4G"
}]

所以在上面的示例中,list_1 主机名字段将包含在 list_2 ref_no 中,并且将匹配前两条记录,然后在新的 list_3 中创建

我觉得我可以在 iterrtools 中做到这一点,但我不确定如何? 谢谢

想要的输出:

list_3 = [{
    "id": 249,
    "ref_no": "AB9472 - 015632584",
    "rssi": "-75.0",
    "circuit_type": "4G",
    "bytes_in": 0,
    "rsrq": -50,
    "hostname": "AB9472"
},
{
    "id": 17,
    "ref_no": "DF4845 - 8984494",
    "rssi": "-20.0",
    "circuit_type": "4G",
    "bytes_in": 0,
    "rsrq": -90,
    "hostname": "DF4845"
}]

【问题讨论】:

  • 您能添加一个预期的输出吗?
  • 嗨,我已经添加了,谢谢
  • 而且一定要用itertools吗?
  • 您知道相关字段的名称吗?即如果id 意外出现在hostname 中怎么办?

标签: python


【解决方案1】:

试试这个:

list_3 = []
for i in list_1:
    for j in list_2:
        if i['hostname'] == j['ref_no'].split("-")[0].strip():
            list_3.append({**i,**j})

print(list_3)

【讨论】:

    【解决方案2】:

    您的问题基本上是extend 另一个字典的字典。

    跟随this answer,我建议你可以使用dict1.update(dict2)

    当第一个列表的每个元素与第二个列表的每个元素匹配时,这是您的问题的示例代码。

    # Both lists have matched order
    len2 = len(list_2)   # Use length of list_2 because it shorter
    list_3=list_1[:len2] # list_3 contains 2 first elements of list_1
    for i in range(len2):
        list_3[i].update(list_2[i])  # Each element is a dict, so use .update() for join 2 dicts
    

    【讨论】:

    • @FZs,我更新了一些描述。谢谢提醒。
    【解决方案3】:

    假设您基本上是在 hostnameref_no 的第一部分进行“加入”(ref_no 的格式相同),我将提出以下程序(使用 Pandas 来做举重):

    # Convert to pandas dataframes to abstract the merging
    import pandas as pd
    df_1 = pd.DataFrame(list_1)
    df_2 = pd.DataFrame(list_2)
    
    # Extract the hostname for merging
    df_2['hostname'] = df_2['ref_no'].apply(lambda x: x.split(' - ')[0])
    
    # Merge the dataframes - using outer-join to keep all information
    # User inner to remove those that have no matches
    df_3 = pd.merge(df_1, df_2, how='outer', on='hostname')
    
    # Convert back to a list
    list_3 = df_3.to_dict('records')
    

    【讨论】:

      【解决方案4】:

      遍历 list_2 并在主机名匹配时从 list_1 获取值:

      list_3 = list_2
      for dataDict1 in list_3:
          refNo = dataDict1["ref_no"].split()[0]
          print(refNo)
          for dataDict2 in list_1:
              if refNo == dataDict2["hostname"]:
                  dataDict1["hostname"] = refNo
                  dataDict1["rsrq"] = dataDict2["rsrq"]
                  dataDict1["bytes_in"] = dataDict2["bytes_in"]
                  break
      print(list_3)
      

      输出:

      [{'bytes_in': 0,
        'circuit_type': '4G',
        'hostname': 'AB9472',
        'id': 249,
        'ref_no': 'AB9472 - 015632584',
        'rsrq': -50,
        'rssi': '-75.0'},
       {'bytes_in': 0,
        'circuit_type': '4G',
        'hostname': 'DF4845',
        'id': 17,
        'ref_no': 'DF4845 - 8984494',
        'rsrq': -90,
        'rssi': '-20.0'}]
      

      【讨论】:

        【解决方案5】:
        list_1 = [{
            "bytes_in": 0,
            "rsrq": -50,
            "hostname": "AB9472"
        },
        {
            "bytes_in": 0,
            "rsrq": -90,
            "hostname": "DF4845"
        },
        {
            "bytes_in": 0,
            "rsrq": "None",
            "hostname": "FC4848"
        }
        ]
        
        list_2 = [{
            "id": 249,
            "ref_no": "AB9472 - 015632584",
            "rssi": "-75.0",
            "circuit_type": "4G"
        },
        {
            "id": 17,
            "ref_no": "DF4845 - 8984494",
            "rssi": "-20.0",
            "circuit_type": "4G"
        }]
        
        list_3 = []
        
        for fs in list_1:
            for sl_fs in list_2:
                if sl_fs['ref_no'].split()[0] == fs['hostname']:
                    list_3.append({**sl_fs, **fs})
        
        

        【讨论】:

          猜你喜欢
          • 2021-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-07
          • 2017-05-01
          • 1970-01-01
          相关资源
          最近更新 更多