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

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

示例输入:

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

期望输出:

{1:89, 2:3, 3:0, 4:5}
2006390 次浏览

备注:对于Python 3.7+,请参阅这个答案

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

最简单的方法是使用#0,它会记住元素插入的顺序:

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]: odOut[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 892 33 04 5

python3

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

In [13]: for k, v in od.items(): print(k, v)....:1 892 33 04 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控制台上的显示方式。

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

在Python 2.4及以上版本中:

mydict = {'carl':40,'alan':2,'bob':1,'danny':3}
for key in sorted(mydict):print "%s: %s" % (key, mydict[key])

提供:

alan: 2bob: 1carl: 40danny: 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#0库留档

>>> 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 892 33 04 5

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

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

但是在使用pprint时,它会返回排序的字典

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

找到另一种方法:

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

upd:
1.这也对嵌套对象进行排序(感谢@DanielF)。
2. python字典是无序的,因此这只适用于print或分配给str。

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

做你想做的最简单的方法是创建一个collections.OrderedDict,按排序顺序插入元素。

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

如果您需要迭代,正如上面其他人所建议的,最简单的方法是迭代排序的键。

打印按键排序的值:

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

获取按键排序的值列表:

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

有许多Python模块提供字典实现,它们自动按排序顺序维护键。考虑已排序容器模块,它是纯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)]

SortedDicttype类型还支持索引位置查找和删除,这在内置的字典类型中是不可能的。

>>> 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 892 33 04 5

你们把事情弄复杂了…其实很简单

from pprint import pprintDict={'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 = ll2.append(0)l3 = []for repeater in range(0, len(l)):smallnum = float("inf")for listitem in l2:if listitem < smallnum:smallnum = listiteml2.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)]

因此,通过将其更改为键,值和项目,您可以按照您想要的方式打印。

最简单的解决方案是,您应该获得一个按排序顺序排列的关键字列表,然后遍历字典。例如

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 30b 13d 4c 2a 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 OrderedDictsorted_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 valuesfor key in sorted(dict1.keys()):if not key in dict2:    # Depending on the goal, this line may not be neccessarydict2[key] = dict1[key]

更清楚地说:

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2}dict2 = {}                  # create an empty dict to store the sorted     valuesfor key in sorted(dict1.keys()):if not key in dict2:    # Depending on the goal, this line may not be  neccessaryvalue = 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中的键排序。

或使用pandas

演示:

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

见:

相关文档

整只大熊猫的文档

我想出了单行字典排序。

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

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

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

对于问题的表述方式,这里最多的答案是正确回答。

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

这将避免每次调用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()))}

使用Lambdas

排序并不总是严格按升序或降序排序。要进行更多条件排序,请使用上述方法和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 OrderedDictfrom sortedcontainers import SortedDictimport 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)

正如我们所看到的,Grant Jenks的解决方案是迄今为止最快的。