如何使用元组值的自定义比较器创建字典的排序表示形式?



我正在尝试弄清楚如何以通用方式创建带有值(元组)的字典的排序表示,并使用 Python 3 中的值的自定义比较器。

我已经阅读了这些主题,但我仍在挣扎:

按值对 Python 字典进行排序

如何在 Python 3 中使用自定义比较函数?

作为一个具体的例子,人们可以将我试图解决的问题视为,"获取按总成本排序的产品列表,给定一个字典,其中包含客户结账时的产品(密钥),以及每个产品的数量和成本(存储为 2 元组)。在python 2中,可以使用这样的东西:

checkout_dict = {'Apples': (1, 3), 'Oranges': (3, 3), 'Grapes': (7, 1),
'Cheese': (10, 1), 'Crackers': (4, 4)}

from operator import itemgetter

def sort_dict(dict, comparison_func):
return sorted(dict.iteritems(), key=itemgetter(1),
cmp=comparison_func)

def cmp_total_cost(product_data_1, product_data_2):
total_product_cost_1 = (product_data_1[0]) * (product_data_1[0])
total_product_cost_2 = (product_data_2[0]) * (product_data_2[0])
return total_product_cost_2 - total_product_cost_1

print sort_dict(checkout_dict, cmp_total_cost)

预期输出如下所示:

[('Crackers', (4, 4)), ('Cheese', (10, 1)), ('Oranges', (3, 3)),
('Grapes', (7, 1)), ('Apples', (1, 3))]

但是在 Python 3 中,sortedcmp参数已被弃用,相反,我们需要将该行为作为key参数的一部分包含在内。

我知道我们需要使用类似functools模块中的cmp_to_key函数之类的东西,但我无法思考如何保持所有内容通用化。我对如何将itemgetter(1)cmp_to_key函数和自定义比较函数结合使用感到困惑。

另外,我知道通过上面的例子,我可以轻松地先遍历字典,计算总成本,然后进行排序,但我正在寻找一种通用解决方案,我可以应用于许多不同类型的比较。

注意

我也希望它尽可能高性能。我发现一些信息表明,使用operator.itemgetter确实可以帮助加快速度: 在 Python 中按值对字典进行排序(改进了?

如果您只想获取元组列表,按第一个元素乘以第二个元素排序,这将可以:

sorted(checkout_dict.items(), key=lambda item: item[1][0] * item[1][1])
#  [('Apples', (1, 3)), ('Grapes', (7, 1)), ('Oranges', (3, 3)), ('Cheese', (10, 1)),
#   ('Crackers', (4, 4))]
# or in the other way around
sorted(checkout_dict.items(), key=lambda item: item[1][0] * item[1][1], reverse=True)
# [('Crackers', (4, 4)), ('Cheese', (10, 1)), ('Oranges', (3, 3)), ('Grapes', (7, 1)), 
#  ('Apples', (1, 3))]

相关内容

最新更新