首页 > 解决方案 > 在比较字典列表后,编写 Python 函数以返回对应于给定输入的最大值的更好方法

问题描述

我有一个字典列表如下,

test = [{'a':100, 'b':1, 'd':3.2},
    {'a':200, 'b':5, 'd':8.75},
    {'a':500, 'b':2, 'd':6.67},
    {'a':150, 'b':7, 'd':3.86},
    {'a':425, 'b':2, 'd':7.72},
    {'a':424, 'b':2, 'd':7.72}]

给定一个“b”值,我需要找到“d”的最大值并在该字典中提取“a”的相应值。如果有平局,则取'a'的最高值。例如 {a:424, b:2, d:7.72} 和 {a:424, b:2, d:7.72} 有 b = 2 并且它们对应的 d 值相等。在这种情况下,我返回 a = 425。

以下代码运行正常。但是,我想知道优化此问题或使用匿名函数 (lambda) 解决此问题的可能方法。

def gerMaxA(bValue):
  temporary_d = -999.99
  temporary_a = 0
  for i in test:
      if i['b'] == bValue:
          if i['d'] > temporary_d:
              temporary_a = i['a']
              temporary_d = i['d']
          elif i['d'] == temporary_d:
              if i['a'] >= temporary_a:
                  temporary_a = i['a']
  ans = (temporary_a, temporary_d)
  return ans

欣赏任何见解。

标签: pythondictionaryoptimization

解决方案


但是,我想知道优化此问题或使用匿名函数 (lambda) 解决此问题的可能方法。

“优化”是一条红鲱鱼 - 你不能简单地在空白中“优化”某些东西,你必须优化它以获得某些质量(速度,内存使用等)

相反,我将展示如何使代码更简单、更优雅。理论上这对于 Stack Overflow 来说是题外话,但是如果我尝试将人员派往其他地方,IMX 系统就不能很好地工作。

给定一个'b'值

这意味着我们将选择列表中满足条件的元素(即,'b'值与目标匹配)。另一个词是过滤;虽然 Python 确实有一个内置函数,但为此目的使用推导式或生成器表达式filter通常更简洁、更符合 Python 风格。由于我们将对结果进行进一步处理,因此我们不应该选择。

我需要找到'd'的最大值

更准确地说:您会看到具有最大值的元素'd'。或者,正如我们在 Python 世界中所想的那样,最大元素,以 'd'. 这是内置的,使用max函数。由于我们将直接向此函数提供数据,因此我们不关心构建容器,因此我们将在第一步中选择生成器表达式。

第一步看起来像这样,意思就是它所说的,从左到右阅读:

(element for element in test if element['b'] == b_value)

“生成器(())产生:elementfor每个都element找到in test,但只包括它if的值是element” 。['b']== b_value

在第二步中,我们将max调用包装起来,并提供适当的key函数。这确实是我们可以使用的地方lambda

max(
    (element for element in test if element['b'] == b_value),
    key=lambda element:(element['d'], element['a'])
)

lambda是一个将给定element值转换为该对值的函数;max然后将根据每个字典产生的值比较过滤后的字典lambda

或者,我们可以使用命名函数 - lambda 是相同的东西,只是没有名称并且对可以在其中执行的操作有限制:

def my_key(element):
    return element['d'], element['a']

# and then we do
max((element for element in test if element['b'] == b_value), key=my_key)

或者我们可以使用标准库:

from operator import itemgetter
max((element for element in test if element['b'] == b_value), key=itemgetter('d', 'a'))

当然,最后一步只是['a']从结果中提取值max


推荐阅读