python dict根据具有两个部分的值排序,一个在升序中,另一个在降序中

时间:2015-02-17 15:43:51

标签: python sorting dictionary

我有以下词典:

{'a1': (45, 8.2), 'a2': (80, 3.2), 'a3': (50, 4.2), 'a4': (80, 2.2)}

要对它进行排序,我会这样做:

import operator
sorted_d = sorted(d.items(),key=operator.itemgetter(1),reverse= True)

和sorted_d现在是:

[('a2', (80, 3.2)), ('a4', (80, 2.2)), ('a3', (50, 4.2)), ('a1', (45, 8.2))]

我希望它在哪里:

[('a4', (80, 2.2)), ('a2', (80, 3.2)), ('a3', (50, 4.2)), ('a1', (45, 8.2))]

值的第一部分按降序排列,第二部分值按升序排列。

实现预期产量的任何想法?

1 个答案:

答案 0 :(得分:4)

你需要提供一个元组来排序。 否定要排序的第一个条目以强制降序排序:

sorted(d.items(), key=lambda i: (-i[1][0], i[1][1]))

请注意,reverse=True参数已消失。

演示:

>>> d = {'a1': (45, 8.2), 'a2': (80, 3.2), 'a3': (50, 4.2), 'a4': (80, 2.2)}
>>> sorted(d.items(), key=lambda i: (-i[1][0], i[1][1]))
[('a4', (80, 2.2)), ('a2', (80, 3.2)), ('a3', (50, 4.2)), ('a1', (45, 8.2))]

我们在这里所做的只是利用Python序列按字典顺序排序的事实;如果您要比较两个元组,则会比较第一个元素,并且仅当它们与第二个位置中的元素匹配时才会被考虑,依此类推。请参阅documentation on comparison expressions

  

使用相应元素的比较,按字典顺序比较元组和列表。 [...]如果不相等,则序列的顺序与它们的第一个不同元素相同。

通过提供元组作为每个条目的排序值,我们可以提供有关如何对第一个元素相同的项目进行排序的其他信息。

你不能简单地在这里使用reverse,因为它在向前排序后反转整个列表,并且它不提供反转子组的选项。否定技巧只是在零的其他方向上提供整数,这也会导致排序顺序反转。当第一个元素匹配时,sort继续使用相同正向的第二个元素。