原文: Sort Dictionary by Value in Python – How to Sort a Dict

在 Python 中,字典默认情况下是无序的。所以,有时候,你想按键或值对字典进行排序,以使查询更容易。

问题是按值对字典进行排序从来都不是一件简单的事情。这是因为 Python 没有一个内置的方法来做这件事。

然而,我想出了一个按值排序字典的方法,这就是我将在本文中向你展示的方法。

我们将讨论的内容

  • 如何用 sorted() 方法对数据进行排序
  • sorted() 方法如何工作
  • sorted() 方法的参数
  • 如何用 sorted() 方法对一个字典进行排序
  • 如何将结果列表转换为一个字典
  • 如何以升序或降序的方式对字典的值进行排序
  • 总结

如何使用 sorted() 方法对数据进行排序

sorted() 方法对诸如列表、元组和字典等可迭代数据进行排序。但它只按键排序。

sorted() 方法将排序后的项目放在一个列表中。这是我们必须解决的另一个问题,因为我们希望字典排序后仍然是一个字典。

例如,sorted() 将下面的列表按字母顺序排列:

persons = ['Chris', 'Amber', 'David', 'El-dorado', 'Brad', 'Folake']
sortedPersons = sorted(persons)

print(sortedPersons)
# Output: ['Amber', 'Brad', 'Chris', 'David', 'El-dorado', 'Folake']

sorted() 方法将下面元组中的数字按升序排序:

numbers = (14, 3, 1, 4, 2, 9, 8, 10, 13, 12)
sortedNumbers = sorted(numbers)

print(sortedNumbers)
# Output: [1, 2, 3, 4, 8, 9, 10, 12, 13, 14]

如果你对一个字典使用 sorted() 方法,只有键会被返回,并且它将是一个列表:

my_dict = { 'num6': 6, 'num3': 3, 'num2': 2, 'num4': 4, 'num1': 1, 'num5': 5}
sortedDict = sorted(my_dict)

print(sortedDict)
# ['num1', 'num2', 'num3', 'num4', 'num5', 'num6']

这不是你想要的结果。你想让字典按值排序并保持为字典。这就是我接下来要告诉你的。

sorted() 方法如何运行

要对字典进行排序,我们仍然要使用 `sorted()d 函数,但要用一种更复杂的方法。别担心,我将解释你需要知道的一切。

既然我们仍然要使用 sorted() 方法,那么现在是时候详细解释 sorted() 方法了。

sorted() 方法的参数

sorted() 方法最多可以接受 3 个参数:

  • iterable - 要迭代的数据,它可以是一个元组、列表或字典
  • key - 一个可选的值,帮助你进行自定义排序操作的函数
  • reverse - 另一个可选的值,它帮助你以升序或降序排列排序的数据

如果你猜对了,key 就是我们要传入 sorted() 方法以得到按值排序的字典的参数。

现在,是时候按值对我们的字典进行排序并确保它仍然是一个字典了。

如何用 sorted() 方法对一个字典进行排序

为了正确地用 sorted() 方法按值对字典进行排序,你必须做以下工作:

  • 将字典作为第一个值传递给 sorted() 方法
  • 在字典上使用 items() 方法来检索它的键和值
  • 写一个 lambda 函数来获取用 item() 方法检索的值

这里有一个例子:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
print(sorted_footballers_by_goals)

正如我前面说的,我们必须得到字典的那些值,这样我们就可以按值对字典进行排序。这就是为什么你可以在 lambda 函数中看到 1

1 代表值的索引,而键是 0。记住,程序员是从 0 开始计数的,而不是 1。

用上面的代码,我得到了下面的结果:

# [('Cruyff', 104), ('Eusebio', 120), ('Messi', 125), ('Ronaldo', 132), ('Pele', 150)]

下面是完整的代码,这样你就不会感到困惑:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
print(sorted_footballers_by_goals)

# [('Cruyff', 104), ('Eusebio', 120), ('Messi', 125), ('Ronaldo', 132), ('Pele', 150)]

你可以看到字典里的值已经按升序排序。你也可以按降序排序。但我们稍后再看,因为我们得到的结果还有一个问题。

问题是这个字典已经不是一个字典了。各个键和值被放在一个元组中,并进一步浓缩为一个列表。记住,你用 sorted() 方法得到的结果都是放在一个列表中。

我们已经能够按值对字典中的项目进行排序了,剩下的就是把它转换回一个字典。

如何将结果列表转换为一个字典

要将结果列表转换为字典,你不需要再写一个复杂的函数或一个循环,你只需要把保存结果列表的变量传给 dict() 方法。

converted_dict = dict(sorted_footballers_by_goals)
print(converted_dict)
# Output: {'Cruyff': 104, 'Eusebio': 120, 'Messi': 125, 'Ronaldo': 132, 'Pele': 150}

记得我们将排序后的字典保存在名为 sorted_footballers_by_goals 的变量中,所以它是我们需要传递给 dict() 的变量。

完整的代码看起来像这样:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
converted_dict = dict(sorted_footballers_by_goals)

print(converted_dict)
# Output: {'Cruyff': 104, 'Eusebio': 120, 'Messi': 125, 'Ronaldo': 132, 'Pele': 150}

就是这些啦!我们已经能够对字典中的项目进行分类,并将其转换为字典。

如何以升序或降序的方式对字典的值进行排序

记住 sorted() 方法接受第三个值,叫做 reverse

reverse 的值为 True 时,将以降序排列排序后的字典。

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1], reverse=True)
converted_dict = dict(sorted_footballers_by_goals)

print(converted_dict)
# Output: {'Pele': 150, 'Ronaldo': 132, 'Messi': 125, 'Eusebio': 120, 'Cruyff': 104}

你可以看到输出是相反的,因为我们把 reverse=True 传给 sorted() 方法。

如果你根本没有设置 reverse,或者你把它的值设置为 false,字典将以升序排列。这就是默认情况。

总结

恭喜你!尽管在 Python 中没有一个内置的方法或函数可以使用,但你现在可以按值对字典进行排序。

然而,当我准备写这篇文章时,有件事引起了我的好奇心。记得我们可以直接在字典上使用 sorted() 。这样做的结果是一个列表,尽管我们只得到了键而不是值。

如果我们用 dict() 方法将这个列表转换为一个字典,会怎么样?你认为我们能得到想要的结果吗?让我们来看看:

my_dict = { 'num6': 6, 'num3': 3, 'num2': 2, 'num4': 4, 'num1': 1, 'num5': 5}
sortedDict = sorted(my_dict)

converted_dict = dict(sortedDict)
print(converted_dict)
"""
Output: 
dict_by_value.py
Traceback (most recent call last):
  File "sort_dict_by_value.py", line 17, in <module>
    converted_dict = dict(sortedDict)
ValueError: dictionary update sequence element #0 has length 4; 2 is required
"""

我们得到了一个错误!这是因为如果你想从一个列表中创建一个字典,你必须使用字典推导。如果你对这种类型的数据使用字典推导,你就必须为所有的项指定一个值。这就违背了按值排序的目的,所以这不是我们想要的。

如果你想了解更多关于字典推导的信息,可以阅读这篇文章

谢谢你阅读本文!