在Python字典中找到最接近的值并返回其键

时间:2018-10-16 21:10:25

标签: python dictionary

我有一个价值

+ echo elbv2 modify-listener --listener-arn arn:aws:elasticloadbalancing:us-east-1:1234567890:listener/app/my-alb/123456789 --default-actions '[{"Type": "redirect", "RedirectConfig": {"Protocol": "HTTPS", "Port": "443", "Host": "#{host}", "Query": "#{query}", "Path": "/#{path}", "StatusCode": "HTTP_301"}}]'
elbv2 modify-listener --listener-arn arn:aws:elasticloadbalancing:us-east-1:1234567890:listener/app/my-alb/123456789 --default-actions '[{"Type": "redirect", "RedirectConfig": {"Protocol": "HTTPS", "Port": "443", "Host": "#{host}", "Query": "#{query}", "Path": "/#{path}", "StatusCode": "HTTP_301"}}]'

此外,与此类似的字典

value = 0.04532

我只想简单地返回字典中与我的原始值最接近的值的键,在这种情况下为{'1': 0.02827, '2': 0.0, '3': 0.09827, '4': 0.04533}

我发现了一篇较旧的帖子,内容与此类似

4

这将返回元组newValue = value answer = min(dict.items(), key=lambda (_, value): abs(value - newValue)) ,而我只想要键(作为int)。 此外,我在理解该代码的确切功能方面遇到了麻烦。

是否有一种更干净的方法来完成此任务?

3 个答案:

答案 0 :(得分:2)

您可以使用序列解压缩来解压缩tuple结果:

value = 0.04532
d = {'1': 0.02827, '2': 0.0, '3': 0.09827, '4': 0.04533}

res_key, res_val = min(d.items(), key=lambda x: abs(value - x[1]))

print(res_key, res_val, sep=', ')

4, 0.04533

一半的问题似乎出在您选择的变量上。确保您不遮盖类别名称,例如叫字典d,而不叫dict。同样,请勿将lambda的自变量命名为已经定义的变量。

否则,通过min进行的逻辑工作如下:

  1. 获取从d.items中提取的每个元组,即键值对。
  2. 将函数lambda x: abs(value - x[1])应用于每个元组,即计算与value的绝对差。
  3. 计算来自lambda函数的最小结果,并返回提供的参数,在这种情况下为tuple中的 d.items

注意PEP 3113从Python 3.x中删除了元组参数解包,这就是为什么我们必须通过x[1]中的lambda显式提取第一个值的原因。

答案 1 :(得分:2)

您引用的代码只是在字典中的键值对之间循环,计算与期望值的差,并返回最小键值对。

要获取值,只需执行以下操作:

answer = min(dict.items(), key=lambda (_, value): abs(value - newValue))[1]
  • 请注意,上面的索引为[1]

确定要将其作为int类型,它将四舍五入为最接近的整数

我建议只用float()包裹上面的语句

答案 2 :(得分:2)

dict.items为您提供字典的((键,值)对。

>>> d = {'1': 0.02827, '2': 0.0, '3': 0.09827, '4': 0.04533}
>>> d.items()
dict_items([('1', 0.02827), ('3', 0.09827), ('2', 0.0), ('4', 0.04533)])

返回值是可迭代的,因此可以传递给min

min还带有关键字参数key,该参数必须是可调用的(通常是函数)。这是min评估其第一个参数的元素以找到最小值的标准。

这是一个简单得多的示例。假设我们需要在列表列表中找到最短的列表。

>>> lists = [[1, 2], [1, 2, 3], [5]]
>>> min(lists, key=len)
[5]

min遍历lists,为len(sublist)中的每个sublist调用lists并返回len(sublist)最小的元素。

检查,建议的解决方案,

lambda (_, value): abs(value - newValue)

是一个(匿名)函数(使用Tuple Parameter Unpacking,该函数在Python 3中不再起作用)应该获取一个项(一个(键,值)对)并返回abs(value - newValue),该函数测量接近程度value代表newValue

如果lambda使您感到困惑,则可以按照以下方法将Python 3中的key函数编写为普通函数。

>>> def criterion(dict_item):
...     key, value = dict_item # unpack
...     return abs(value - newValue)

您现在可以发布

>>> newValue = 0.04532
>>> d = {'1': 0.02827, '2': 0.0, '3': 0.09827, '4': 0.04533}
>>> 
>>> min(d.items(), key=criterion)
('4', 0.04533)

如果您只想将密钥作为整数,请从索引0获取,然后将其转换为int

>>> int(min(d.items(), key=criterion)[0])
4

最后,不要使用变量名dict,该名称应为内置字典类型保留。