如何在Python中按数字顺序对字典按键进行排序

28

这就是字典的样子:

{'57481': 50, '57480': 89, '57483': 110, '57482': 18, '57485': 82, '57484': 40}  

我希望按照数字顺序对字典进行排序,结果应为:

{'57480': 89, '57481': 50, '57482': 18, '57483': 110, '57484': 40, '57485': 82} 

我尝试了sorted(self.docs_info.items),但它没有起作用。


1
可能是Python字典按键排序的重复问题。 - alecxe
这个回答解决了你的问题吗?如何按键对字典进行排序? - Vega
4个回答

27

如果您只需要按键排序,那么您已经完成了95%。假设您的字典似乎叫做docs_info

for key, value in sorted(docs_info.items()): # Note the () after items!
    print(key, value)

由于字典的键总是唯一的,对docs_info.items()(一个元组序列)调用sorted等同于仅按键排序。

请注意,包含数字的字符串排序不直观!例如,"11""2"要“小”。如果您需要按数字排序,建议将键改为int而不是str,例如:

int_docs_info = {int(k) : v for k, v in docss_info.items()}

当然,这只是改变了您访问字典元素的顺序,这通常已经足够了(因为如果您不访问它,那么排序有什么意义呢?)。如果由于某种原因您需要对字典本身进行“排序”,那么您就必须使用 collections.OrderedDict,它会记住向其中插入项的顺序。因此,您可以首先对字典进行排序(如上所示),然后从排序后的(键、值)对中创建一个 OrderedDict

sorted_docs_info = collections.OrderedDict(sorted(docs_info.items()))

如果是多维字典,你会如何修改这个答案?例如,一个四维字典,像这样:docs_info{1:{2:{3:{55555}}}} - ulkas
@ulkas 提取任何子字典并像其他字典一样进行排序。如果您希望将其展平为单个维度,请先这样做,然后再进行排序。展平逻辑将比您实现的任何排序行为更复杂。 - Henry Keiter

10

标准的Python字典是“无序”的。您可以使用一个 OrderedDict,请参阅文档

from collections import OrderedDict

d = {'57481': 50, '57480': 89, '57483': 110, '57482': 18, '57485': 82, '57484': 40}
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
# OrderedDict([('57480', 89), ('57481', 50), ('57482', 18), ('57483', 110), ('57484', 40), ('57485', 82)])

lambda x: 2*x+1 实际上与 def f(x): return 2*x+1 几乎相同。我将其用作编写选择元组中第一个元素(键)的函数的更短方式。 - elyase

5
如果重复排序元素并将其插入到有序字典中速度过慢,则考虑在PyPI上使用其中一种已排序的字典实现。 SortedDict 数据类型可以高效地维护其键的排序顺序。 sortedcontainers 模块包含这样的实现之一。

从 PyPI 进行安装非常容易:

pip install sortedcontainers

如果您无法通过pip install安装程序,则可以从开源代码库中复制sortedlist.py和sorteddict.py文件。SortedContainers是用纯Python实现的,但速度快如C语言实现。

安装完成后,只需执行以下步骤:

In [1]: from sortedcontainers import SortedDict

In [6]: SortedDict({'57481': 50, '57480': 89, '57483': 110, '57482': 18, '57485': 82, '57484': 40})
Out[6]: SortedDict({'57480': 89, '57481': 50, '57482': 18, '57483': 110, '57484': 40, '57485': 82})

sortedcontainers模块还维护了几种流行实现的性能比较


4
在Python 3中,sorted()函数有一个可选参数key。在3.6+版本中,dict保持插入的顺序。

key指定了一个带有一个参数的函数,用于从iterable的每个元素中提取比较键(例如,key=str.lower)。默认值为None(直接比较元素)。

因此,OP想要的可以这样实现。
>>> d = {'57481': 50, '57480': 89, '57483': 110, '57482': 18, '57485': 82, '57484': 40}
>>> for key, value in sorted(d.items(), key=lambda item: int(item[0])):
...     print(key, value)
57480 89
57481 50
57482 18
57483 110
57484 40
57485 82

或者,如果OP想要创建一个新的排序字典。
>>> d = {'57481': 50, '57480': 89, '57483': 110, '57482': 18, '57485': 82, '57484': 40}
>>> d_sorted = {key:value for key, value in sorted(d.items(), key=lambda item: int(item[0]))}
>>> d_sorted
{'57480': 89, '57481': 50, '57482': 18, '57483': 110, '57484': 40, '57485': 82}

d.items() 返回一个元组列表,例如 ('57480': 89) 等。Lambda 函数将这个元组作为参数,并将 int 函数应用于第一个值。然后使用此结果进行比较。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接