字典运算
问题
如何在数据字典中执行计算操作(例如,求最大最小值,排序等)?
解决方法
示例字典如下(股票名称和价格的映射):
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
这里能够进行计算的是价格,这里可以借助 zip()
函数将键和值进行反转。示例代码如下(求价格最大和最小的股票)
max_price = max(zip(prices.values(), prices.key()))
# (612.78, 'AAPL')
min_price = min(zip(prices.values(),prices.key())
# (10.75, 'FB')
类似还有使用 zip()
和 sorted()
两者配合排列字典数据:
prices_sorted = sorted(zip(prices.values(), prices.key()))
# [(10.75, 'FB'), (37.2, 'HPQ'),
# (45.23, 'ACME'), (205.55, 'IBM'),
# (612.78, 'AAPL')]
这里需要注意的地方是,zip()
函数创建的是一个只能访问一次的迭代器,第二次访问会产生错误:
prices_and_names = zip(prices.values(), prices.keys())
print(min(prices_and_names)) # 正常输出
print(max(prices_and_names)) # 抛出 ValueError 异常
代码解析
正常情况下,max
和 min
对字典进行操作时,仅仅作用于键而不是值。例如:
min(prices)
# 'AAPL'
max(prices)
# 'IBM'
如果想作用于值的话,可以尝试使用字典的 values()
方法:
min(prices.values())
# 10.75
max(prices.values())
# 612.78
但是这里看不出最小最大值对应的究竟是哪个股票。
在这里,可以在 min()
和 max()
函数种提供 key
函数参数来获取最小值或最大值对应的键的信息,比如:
min(prices, key=lambda k: prices[k])
# 'FB'
max(prices, key=lambda k: prices[k])
# 'AAPL'
但是,这里又会有一个问题,要得到值,又得执行一次查询的操作,示例如下:
min_value = prices[min(prices, key=lambda k: prices[k])]
而在解决方法中提及的 zip()
方法,通过将字典键值进行反转就能够解决上面的问题。当比较两个元组(值,键)的时候,会先比较第一个元素值
,再比较第二个元素键
,这样就能够用简单的代码实现求最值和排序操作。
这里特意提及下,当进行反转(值,键)后,多个实体的值重复时,键会觉得返回的结果。示例如下:
>>> prices = { 'AAA' : 45.23, 'ZZZ': 45.23 }
>>> min(zip(prices.values(), prices.keys()))
(45.23, 'AAA')
>>> max(zip(prices.values(), prices.keys()))
(45.23, 'ZZZ')
>>>