鱼C论坛

 找回密码
 立即注册
查看: 2717|回复: 0

[技术交流] 1.8 字典的运算

[复制链接]
发表于 2020-3-19 13:33:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
字典的运算


问题

怎样在数据字典中执行一些计算操作(比如求最小值、最大值、排序等等)?

解决方案

考虑下面的股票名和价格映射字典:

  1. prices = {
  2.     'ACME': 45.23,
  3.     'AAPL': 612.78,
  4.     'IBM': 205.55,
  5.     'HPQ': 37.20,
  6.     'FB': 10.75
  7. }
复制代码


为了对字典值执行计算操作,通常需要使用 zip() 函数先将键和值反转过来。

比如,下面是查找最小和最大股票价格和股票值的代码:

  1. min_price = min(zip(prices.values(), prices.keys()))
  2. # min_price is (10.75, 'FB')
  3. max_price = max(zip(prices.values(), prices.keys()))
  4. # max_price is (612.78, 'AAPL')
复制代码


类似的,可以使用 zip() 和 sorted() 函数来排列字典数据:

  1. prices_sorted = sorted(zip(prices.values(), prices.keys()))
  2. # prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
  3. #                   (45.23, 'ACME'), (205.55, 'IBM'),
  4. #                   (612.78, 'AAPL')]
复制代码


执行这些计算的时候,需要注意的是 zip() 函数创建的是一个只能访问一次的迭代器。

比如,下面的代码就会产生错误:

  1. prices_and_names = zip(prices.values(), prices.keys())
  2. print(min(prices_and_names)) # OK
  3. print(max(prices_and_names)) # ValueError: max() arg is an empty sequence
复制代码


讨论

如果你在一个字典上执行普通的数学运算,你会发现它们仅仅作用于键,而不是值。比如:

  1. min(prices) # Returns 'AAPL'
  2. max(prices) # Returns 'IBM'
复制代码


这个结果并不是你想要的,因为你想要在字典的值集合上执行这些计算。

或许你会尝试着使用字典的 values() 方法来解决这个问题:

  1. min(prices.values()) # Returns 10.75
  2. max(prices.values()) # Returns 612.78
复制代码


不幸的是,通常这个结果同样也不是你想要的。

你可能还想要知道对应的键的信息(比如那种股票价格是最低的?)。

你可以在 min() 和 max() 函数中提供 key 函数参数来获取最小值或最大值对应的键的信息。比如:

  1. min(prices, key=lambda k: prices[k]) # Returns 'FB'
  2. max(prices, key=lambda k: prices[k]) # Returns 'AAPL'
复制代码


但是,如果还想要得到最小值,你又得执行一次查找操作。比如:

  1. min_value = prices[min(prices, key=lambda k: prices[k])]
复制代码


前面的 zip() 函数方案通过将字典 “反转” 为 (值,键) 元组序列来解决了上述问题。

当比较两个元组的时候,值会先进行比较,然后才是键。

这样的话你就能通过一条简单的语句就能很轻松的实现在字典上的求最值和排序操作了。

需要注意的是在计算操作中使用到了 (值,键) 对。当多个实体拥有相同的值的时候,键会决定返回结果。

比如,在执行 min() 和 max() 操作的时候,如果恰巧最小或最大值有重复的,那么拥有最小或最大键的实体会返回:

  1. >>> prices = { 'AAA' : 45.23, 'ZZZ': 45.23 }
  2. >>> min(zip(prices.values(), prices.keys()))
  3. (45.23, 'AAA')
  4. >>> max(zip(prices.values(), prices.keys()))
  5. (45.23, 'ZZZ')
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 05:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表