【问题标题】:How to get the max value from a dictionary based on conditions如何根据条件从字典中获取最大值
【发布时间】:2021-09-16 17:48:59
【问题描述】:

我有一个字典列表,我想从 'confidence' 获取最大浮点数,其中键 ('key') 相同。

ab = [{'key': 'gdpr.gdpr_compliance.1', 'value': 'Yes', 'idref': '69dbdba4-14d4-4ac8-a318-0d658e4d5b07', 'xpath': '/html/body/p[24]', 'confidence': 0.985},
      {'key': 'gdpr.gdpr_compliance.2', 'value': 'Yes', 'idref': '69e2589a-bbf2-49c3-96fc-01fbee5dde03', 'xpath': '/html/body/p[27]', 'confidence': 0.989},
      {'key': 'data_collected.personally_identifiable_information.1', 'value': 'Yes', 'idref': 'f6819b54-07a7-4839-b0cc-8343eed28342', 'xpath': '/html/body/ul[6]/li[1]', 'confidence': 0.562},
      {'key': 'data_collected.personally_identifiable_information.2', 'value': 'Yes', 'idref': '496400e5-9665-4697-96bc-c55176cdbd02', 'xpath': '/html/body/ul[6]/li[2]', 'confidence': 0.661}]

在这里您可以观察到第一个两个具有 gdpr 的字典,而第三个具有 data_collected 的字典。

这里我不明白我们如何获得最大值

我试着这样做

lis = []
for i in ab:
    spl = i['key'].split('.')[0]
    i['key'] = spl
    if i['key'] == spl:
        lis.append(i['confidence'])
print(lis)

预期的输出应该是:[0.989, 0.661]

【问题讨论】:

  • 你为什么将spl分配给i[key]然后立即检查它们是否相等? (他们显然会!)

标签: python python-3.x list dictionary


【解决方案1】:

当您的数据是基于键的时,我不确定您为什么要获取列表。我自己会使用字典,但话又说回来,也许你只想比较相邻的值,你可以用itertools.groupby 来做。我将在下面包括这两种方法。

字典

maxes = {}
for d in ab:
    confidence = d['confidence']
    spl = d['key'].split('.')[0]
    if spl not in maxes or confidence > maxes[spl]:
        maxes[spl] = confidence
print(maxes)
{'gdpr': 0.989, 'data_collected': 0.661}

分组方式

from itertools import groupby

grouper = groupby(ab, lambda d: d['key'].split('.')[0])
maxes = [(k, max(d['confidence'] for d in g)) for k, g in grouper]
print(maxes)
[('gdpr', 0.989), ('data_collected', 0.661)]

我把钥匙留在这里,但你可以扔掉它们。

lis = [max(d['confidence'] for d in g) for _k, g in grouper]
print(lis)
[0.989, 0.661]

【讨论】:

    【解决方案2】:

    你哪里出错了

    1. 您拆分了i['key'],然后您分配了相同的值。这没有意义。
    2. 第二次你将i['key'] 分配给spl 然后你立即检查它们是否相等。显然他们会的。

    正确的方法

    字典

    highest_value_dict = {}
    for i in ab:
        spl = i['key'].split('.')[0]
        # if no such key, then add it.
        # else check if this key is greater than the one in highest_value_dict
        if spl not in highest_value_dict or highest_value_dict[spl] < i['confidence']:
            highest_value_dict[spl] = i['confidence']
    

    输出:

    {'gdpr': 0.989, 'data_collected': 0.661}
    

    如果你真的想要列表中的值

    list(highest_value_dict.values())
    

    输出:

    [0.989, 0.661]
    

    【讨论】:

      【解决方案3】:

      如下所示。这个想法是使用defaultdict 将密钥映射到最大置信度

      from collections import defaultdict
      ab = [{'key': 'gdpr.gdpr_compliance.1', 'value': 'Yes', 'idref': '69dbdba4-14d4-4ac8-a318-0d658e4d5b07',
             'xpath': '/html/body/p[24]', 'confidence': 0.985},
            {'key': 'gdpr.gdpr_compliance.2', 'value': 'Yes', 'idref': '69e2589a-bbf2-49c3-96fc-01fbee5dde03',
             'xpath': '/html/body/p[27]', 'confidence': 0.989},
            {'key': 'data_collected.personally_identifiable_information.1', 'value': 'Yes',
             'idref': 'f6819b54-07a7-4839-b0cc-8343eed28342', 'xpath': '/html/body/ul[6]/li[1]', 'confidence': 0.562},
            {'key': 'data_collected.personally_identifiable_information.2', 'value': 'Yes',
             'idref': '496400e5-9665-4697-96bc-c55176cdbd02', 'xpath': '/html/body/ul[6]/li[2]', 'confidence': 0.661}]
      
      data = defaultdict(float)
      for entry in ab:
          value = entry['confidence']
          key = entry['key'].split('.')[0]
          if data[key] < value :
              data[key] = value
      
      for k,v in data.items():
          print(f'{k} -> {v}')
      

      输出

      gdpr -> 0.989
      data_collected -> 0.661
      

      【讨论】:

        【解决方案4】:

        我建议使用 O(n) 时间和内存复杂度的解决方案:

        from typing import List
        
        
        def get_maximal_values(data: dict) -> List[float]:
            # Create iterator for extracting needed data
            preparing_data = ((x['key'].split('.')[0], x['confidence']) for x in data)
            
            # Find maximum for each unique key
            result = {}
            for key, confidence in preparing_data:
                result[key] = max(result.get(key, 0), confidence)
            # return only confidence values
            return list(result.values())
        

        【讨论】:

        • 如果置信度为负值,使用 0 作为默认值会导致问题,但我不确定这种可能性有多大
        • 这与Stark Bots's solutionmy dict solution基本相同,只是你将它包装在一个函数中。
        • preparing_data 不是必需的。你可以做for x in data: key = x['key'].split('.')[0]; confidence = x['confidence']
        • *data: List[dict]
        猜你喜欢
        • 1970-01-01
        • 2022-12-02
        • 2013-11-15
        • 1970-01-01
        • 2022-06-28
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多