如何按键对字典进行排序?

示例输入:

{2:3, 1:89, 4:5, 3:0}

期望的输出:

{1:89, 2:3, 3:0, 4:5}

注意:对于Python 3.7+,请参见此答案

标准Python字典是无序的(直到Python 3.7)。即使对(键,值)对进行了排序,也不能将它们存储在字典中以保持排序。

最简单的方法是使用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

正如其他人所提到的,字典本质上是无序的。然而,如果问题只是以有序的方式显示字典,你可以在字典子类中重写__str__方法,并使用这个字典类而不是内置的字典。如。

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}

注意,这不会改变键的存储方式,当你遍历它们时它们返回的顺序等,只是它们在打印时或在python控制台中显示的方式。


字典本身并没有这样的排序条目,如果你想按某种顺序打印它们,这里有一些例子:

在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

(Python低于2.4:)

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的集合库文档:

>>> 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)])

在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

在这里,我找到了一些最简单的解决方案,使用pprint按键对python字典进行排序。 如。

>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99} 
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}

但是当使用pprint时,它将返回排序后的dict

>>> import pprint 
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}

找到了另一种方法:

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

乌利希期刊指南: 1. 这也可以对嵌套对象进行排序(谢谢@DanielF)。 2. Python字典是无序的,因此只适用于打印或赋值给STR。


Python字典是无序的。通常,这不是问题,因为最常见的用例是执行查找。

最简单的方法是创建一个集合。OrderedDict以排序顺序插入元素。

ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])

如果需要迭代,就像上面其他人建议的那样,最简单的方法是迭代排序的键。的例子,

按键排序打印值:

# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
    value = d[k]
    # do something with k, value like print
    print k, value

获取按键排序的值列表:

values = [d[k] for k in sorted(d.keys())]

有许多Python模块提供字典实现,这些字典自动按排序顺序维护键。考虑sortedcontainers模块,它是纯python和像c一样快的实现。此外,还会与其他受欢迎的选项进行性能比较。

如果您需要在迭代的同时不断地添加和删除键/值对,那么使用有序字典是一个不合适的解决方案。

>>> 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

伙计们,你们把事情搞复杂了……非常简单

from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)

输出结果为:

{'A':2,'B':1,'C':3}

2.7中两个方法的时间比较显示它们实际上是相同的:

>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181

>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745 

l = dict.keys()
l2 = l
l2.append(0)
l3 = []
for repeater in range(0, len(l)):
    smallnum = float("inf")
    for listitem in l2:
        if listitem < smallnum:
            smallnum = listitem
    l2.remove(smallnum)
    l3.append(smallnum)
l3.remove(0)
l = l3

for listitem in l:
    print(listitem)

from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
    {'fname': 'Mo', 'lname': 'Mahjoub'},
    {'fname': 'Abdo', 'lname': 'Al-hebashi'},
    {'fname': 'Ali', 'lname': 'Muhammad'}
]
#  This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first. 
for k in sorted (user, key=itemgetter ('fname', 'lname')):
    print (k)

# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
    print (x)

有一种简单的方法来整理字典。

根据你的问题,

解决方案是:

c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y

(其中c是你的字典名。)

这个程序给出如下输出:

[(1, 89), (2, 3), (3, 0), (4, 5)]

如你所愿。

另一个例子是:

d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x

给出输出:['Albert', 'Bill', 'John', 'Lucy', 'Peter']

y=sorted(d.values())
print y

给出输出:[18,24,32,36,41]

z=sorted(d.items())
print z

给出输出:

[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]

因此,通过将其更改为键、值和项,您可以像您想要的那样打印。希望这能有所帮助!


最简单的解决方案是,你应该得到一个dict键排序顺序的列表,然后遍历dict。例如

a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
    print r, a1[r]

以下是输出(按顺序排列)

e 30
b 13
d 4
c 2
a 1

会产生你想要的结果:

 D1 = {2:3, 1:89, 4:5, 3:0}

 sort_dic = {}

 for i in sorted(D1):
     sort_dic.update({i:D1[i]})
 print sort_dic


{1: 89, 2: 3, 3: 0, 4: 5}

但这并不是正确的方法,因为它可以在不同的字典中显示不同的行为,这是我最近学到的。因此,蒂姆在回答我的问题时提出了一个完美的方法,我在这里分享。

from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))

我认为最简单的事情是按键对字典进行排序,并将排序的键:值对保存在一个新的字典中。

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be neccessary
        dict2[key] = dict1[key]

更清楚地说:

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted     values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be  neccessary
        value = dict1[key]
        dict2[key] = value

dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}

temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])

sorted_dict:
         {1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}

对于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字典在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):

考虑了这个新实现的保序方面 一个实现细节,不应该依赖(这可能 将来会有变化,但希望有这个新词典 在语言中实现了几个版本,然后才更改 语言规范要求所有当前的语义保持有序 以及未来的Python实现;这也有助于保存 向后兼容该语言的旧版本 随机迭代顺序仍然有效,例如Python 3.5)。

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

在字典上执行list(d)将返回所有使用的键的列表 在字典中,按插入顺序(如果你想排序,只需使用 排序(d))。

因此,与以前的版本不同,您可以在Python 3.6/3.7之后对字典进行排序。如果你想对包含子字典在内的嵌套字典进行排序,你可以这样做:

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

def dict_reorder(item):
    return {k: dict_reoder(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


您可以根据您的问题按键对当前字典进行排序,从而创建一个新字典。

这是你的字典

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

通过使用lambda函数对这个d排序,创建一个新字典d1

d1 = dict(sorted(d.items(), key = lambda x:x[0]))

D1应为{1:89,2:3,3:0,4:5},根据d中的键进行排序。


或者用熊猫,

演示:

>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
   A  B  C
0  2  1  3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>> 

See:

这方面的文档 整只熊猫的记录


我想出了单行字典排序。

>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in sorted(a.keys())}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]

希望这对你有所帮助。


此函数将根据键对任何字典进行递归排序。也就是说,如果字典中的任何值也是一个字典,它也将根据它的键进行排序。如果您运行在CPython 3.6或更高版本上,则可以简单地更改为使用dict而不是OrderedDict。

from collections import OrderedDict

def sort_dict(d):
    items = [[k, v] for k, v in sorted(d.items(), key=lambda x: x[0])]
    for item in items:
        if isinstance(item[1], dict):
            item[1] = sort_dict(item[1])
    return OrderedDict(items)
    #return dict(items)

有一个简单的方法:

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

s = {k : d[k] for k in sorted(d)}

s
Out[1]: {1: 89, 2: 3, 3: 0, 4: 5} 

我的建议是这样的,因为它允许你在添加项和将来可能需要添加项时对字典排序或保持字典排序:

从头开始构建词典。有第二个数据结构,一个包含键列表的列表。bisect包有一个insort函数,允许插入到一个排序的列表中,或者在完全填充字典后对列表进行排序。现在,当您迭代字典时,您将迭代列表以按顺序访问每个键,而不用担心字典结构的表示(它不是为排序而设计的)。


就问题的表述方式而言,这里的大多数答案都是正确的。

然而,考虑到事情应该如何真正完成,考虑到几十年的计算机科学,让我完全惊讶的是,这里实际上只有一个答案(来自GrantJ用户)建议使用排序关联容器(sortedcontainers),它基于插入点的键对元素进行排序。

这将避免每次调用sort(…)时对性能的巨大影响(至少O(N*log(N)),其中N是元素的数量(逻辑上,这适用于这里建议使用sort(…)的所有此类解决方案)。考虑到对于所有这样的解决方案,sort(…)将需要在每次通过添加/删除元素修改后,当需要以排序方式访问集合时调用…


这里已经有很多答案展示了对Python字典进行排序的流行方法。我想我应该为那些从谷歌来到这里寻找非标准想法的人添加一些不太明显的方法。

样本字典:d = {2: ' c ', 1: ' b ', 0: ' a ', 3: ' d '}

字典理解

# Converts to list, sorts, re-converts to dict
{k: v for k, v in sorted(list(d.items()))}

使用λ

排序并不总是按照严格的升序或降序进行。对于更多的条件排序,使用上述方法结合lamdas:

{k: v for k, v in sorted(d.items(), key=lambda v: ord(v[1]))}

更多的例子

这个帖子已经有足够多的好例子了。有关更多示例,以及边缘情况和奇怪情况,请参阅这篇关于Python中字典排序的文章。


我发现对字典进行排序的一个简单方法是,根据要排序的字典的排序键:值项创建一个新字典。 如果你想对dict ={}排序,使用相关的方法检索它的所有项,使用sorted()函数对它们排序,然后创建新字典。

下面是使用字典理解的代码:

sorted_dict = {k:v for k,v in sorted(dict.items())}

如果你知道你所有的键都是相同的类型,或者有支持'< '(小于,python的__lt__)的类型,那么你可以使用dict(sorted(your_dict.items(), key=lambda _: _[0]))一个容易理解的一行程序


以下是建议解决方案的性能:

from collections import OrderedDict
from sortedcontainers import SortedDict
import json

keys = np.random.rand(100000)
vals = np.random.rand(100000)

d = dict(zip(keys, vals))

timeit SortedDict(d)
#45.8 ms ± 780 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

timeit sorted(d.items())
#91.9 ms ± 707 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

timeit OrderedDict(sorted(d.items(), key=lambda x: x[0]))
#93.7 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

timeit dict(sorted(dic.items()))
#113 ms ± 824 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

timeit OrderedDict(sorted(dic.items()))
#122 ms ± 2.65 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

timeit json.dumps(d, sort_keys=True)
#259 ms ± 9.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

如我们所见,格兰特·詹克斯的解决方案是目前为止最快的。