如何按键对字典排序?

{2:3, 1:89, 4:5, 3:0}{1:89, 2:3, 3:0, 4:5}什么?
我检查了一些帖子,但它们都使用了返回元组的 “排序” 运算符。

答案

标准 Python 字典是无序的。即使您对(键,值)对进行了排序,也无法以保留顺序的方式将它们存储在dict中。

最简单的方法是使用OrderedDict ,它可以记住元素插入的顺序:

In [1]: import collections

In [2]: d = {2:3, 1:89, 4:5, 3:0}

In [3]: od = collections.OrderedDict(sorted(d.items()))

In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])

没关系od的打印方式;它会按预期工作:

In [11]: od[1]
Out[11]: 89

In [12]: od[3]
Out[12]: 0

In [13]: for k, v in od.iteritems(): print k, v
   ....: 
1 89
2 3
3 0
4 5

Python 3

对于 Python 3 用户,需要使用.items()而不是.iteritems()

In [13]: for k, v in od.items(): print(k, v)
   ....: 
1 89
2 3
3 0
4 5

字典本身没有这样的有序项目,如果您想按某种顺序打印它们,下面是一些示例:

在 Python 2.4 及更高版本中:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

for key in sorted(mydict):
    print "%s: %s" % (key, mydict[key])

给出:

alan: 2
bob: 1
carl: 40
danny: 3

(低于 2.4 的 Python :)

keylist = mydict.keys()
keylist.sort()
for key in keylist:
    print "%s: %s" % (key, mydict[key])

资料来源: http : //www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/

Python 的collections库文档中

>>> from collections import OrderedDict

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

对于 CPython / PyPy 3.6 和任何 Python 3.7 或更高版本,可以使用以下方法轻松完成此操作:

>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}

有许多 Python 模块提供字典实现,这些实现将按顺序自动维护键。考虑sortedcontainers模块,它是纯 Python 和快速 C 实现。与其他基准比较的流行选项也进行了性能比较

如果您需要在迭代过程中不断添加和删除键 / 值对,则使用有序 dict 是不适当的解决方案。

>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]

SortedDict 类型还支持索引位置查找和删除,这是内置 dict 类型无法实现的。

>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])

只是:

d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())

for k,v in sd:
    print k, v

输出:

1 89
2 3
3 0
4 5

正如其他人所提到的,字典本质上是无序的。但是,如果问题仅是按顺序显示字典,则可以覆盖字典子类中的__str__方法,并使用此字典类而不是内置dict 。例如。

class SortedDisplayDict(dict):
   def __str__(self):
       return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"


>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}

请注意,这不会改变密钥的存储方式,迭代时它们返回的顺序等,也不会改变它们在print或 python 控制台上的显示方式。

找到了另一种方法:

import json
print json.dumps(d, sort_keys = True)

更新:
1. 这也对嵌套对象进行排序(感谢 @DanielF)。
2. python 字典是无序的,因此可用于打印或仅分配给 str。

在 Python 3 中。

>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
    print (key, D1[key])

1 89
2 3
3 0
4 5

Python 字典在 Python 3.6 之前是无序的。在 Python 3.6 的 CPython 实现中,字典保留插入顺序。从 Python 3.7 开始,这将成为一种语言功能。

在 Python 3.6 的更新日志中( https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-compactdict ):

此新实现的顺序保留方面被认为是实现细节,因此不应依赖(将来可能会更改,但是在更改语言规范之前,希望在几个发行版中使用该新 dict 实现该语言的几个版本为所有当前和将来的 Python 实现强制要求保留顺序的语义;这还有助于保留与仍旧有效的随机迭代顺序的旧版本语言(例如 Python 3.5)的向后兼容性。

在 Python 3.7 的文档中( https://docs.python.org/3.7/tutorial/datastructures.html#dictionaries ):

在字典上执行 list(d)会以插入顺序返回字典中使用的所有键的列表(如果要对其进行排序,请改用 sorted(d))。

因此,与以前的版本不同,您可以在 Python 3.6 / 3.7 之后对字典进行排序。如果要对嵌套的字典(包括其中的子字典)进行排序,则可以执行以下操作:

test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}

def dict_reorder(item):
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

reordered_dict = dict_reorder(test_dict)

https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb