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

时间:2012-01-25 10:54:29

标签: python sorting dictionary

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

31 个答案:

答案 0 :(得分:808)

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

答案 1 :(得分:378)

字典本身没有这样的订购商品,如果你想将它们打印成某些订单,这里有一些例子:

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

答案 2 :(得分:185)

来自Python's collections library documentation

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

答案 3 :(得分:64)

对于python3.6 +,可以通过以下方式轻松完成:

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

答案 4 :(得分:39)

有许多Python模块提供字典实现,可以按排序顺序自动维护密钥。考虑sortedcontainers模块,它是纯Python和快速实现C模块。还有一个performance comparison与其他热门选项相互对照。

如果您需要在迭代的同时不断添加和删除键/值对,则使用有序的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])

答案 5 :(得分:24)

简单地:

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

答案 6 :(得分:23)

正如其他人所提到的,字典本质上是无序的。但是,如果问题仅仅是以有序方式显示字典,则可以覆盖字典子类中的__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控制台一起显示的方式。

答案 7 :(得分:15)

在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

答案 8 :(得分:15)

找到另一种方式:

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

<强> UPD:
1.这也可以对嵌套对象进行排序(感谢@DanielF) 2. python词典是无序的,因此这对于打印或仅分配给str是可以的。

答案 9 :(得分:10)

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

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

答案 10 :(得分:10)

一种简单的方法:

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} 

答案 11 :(得分:8)

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)的文档中:

  

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

与以前的版本不同,您可以在Python 3.6 / 3.7之后对字典进行排序。如果你想对嵌套的dict进行排序,包括里面的sub-dict,你可以这样做:

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

答案 12 :(得分:6)

有一种简单的方法可以对字典进行排序。

根据你的问题,

解决方案是:

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

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

该程序提供以下输出:

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

给出输出:

typeof

因此,通过将其更改为键,值和项目,您可以打印出您想要的内容。希望这有帮助!

答案 13 :(得分:5)

将准确生成您想要的内容:

 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}

但这不是写这样做的方式,因为它可以显示不同字典的不同行为,我最近学到了这些。因此Tim提出了完美的方式在我的查询的回答中,我在这里分享。

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

答案 14 :(得分:4)

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

执行所需操作的最简单方法是创建以排序顺序插入元素的collections.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())]

答案 15 :(得分:4)

我认为最简单的方法是按键对字典进行排序,并在新字典中保存已排序的键:值对。

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

更清楚:

//@*[.='{0}']|//*[.='{0}']

答案 16 :(得分:4)

您可以根据您的问题按键对当前字典进行排序来创建新字典。

这是你的词典

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中的键排序。

答案 17 :(得分:2)

此函数将按其键对所有字典递归进行排序。也就是说,如果字典中的任何值也是字典,那么它也将通过其键进行排序。如果您在CPython 3.6或更高版本上运行,则可以简单地更改为使用DoesNotExist而不是dict

OrderedDict

答案 18 :(得分:1)

我发现对字典进行排序的一种简单方法是根据您尝试排序的已排序键:值项创建一个新字典。 如果要对 dict = {} 进行排序,请使用关联方法检索其所有项目,使用 sorted() 函数对其进行排序,然后创建新字典。

这是使用字典理解的代码:

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

答案 19 :(得分:1)

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

示例字典: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))}

使用 Lambda

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

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

更多示例

这个帖子已经有足够多的好例子了。有关更多示例,以及在 Python 中排序字典的边缘情况和奇数 check out this article

答案 20 :(得分:1)

关于问题的表达方式,此处最多的答案是正确回答。

但是,考虑到数十年来计算机科学的实际情况,应该应该如何完成,所以我完全惊奇地发现这里实际上只有one answer(来自GrantJ位用户)建议使用已排序的关联容器(sortedcontainer),该容器根据插入点处的键对元素进行排序。

这将避免每次sort(...)的每次调用大规模对性能的影响(至少O(N*log(N)),其中N的元素数(从逻辑上讲,建议使用sort(...)的所有此类解决方案。请注意,对于所有此类解决方案,每次需要按排序方式访问集合时,都需要调用sort(...) 之后,通过添加/删除元素对其进行了修改...

答案 21 :(得分:1)

我提出单行字典排序。

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

希望这会有所帮助。

答案 22 :(得分:1)

你们让事情变得复杂......这很简单

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

输出结果为:

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

答案 23 :(得分:1)

最简单的解决方案是你应该得到一个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

答案 24 :(得分:0)

或使用pandas

演示:

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

请参阅:

  

Docs of this

     

Documentation of whole pandas

答案 25 :(得分:0)

document.cookie = 'test_cookie="[AB]cd|ef-gh[IJ]"; path=/';

答案 26 :(得分:0)

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

从头开始构建dict。有第二个数据结构,一个列表,以及您的键列表。 bisect软件包具有insort函数,该函数允许插入排序列表中,或者在完全填充字典后对列表进行排序。现在,当您遍历字典时,您可以遍历列表来按顺序访问每个键,而不必担心dict结构的表示(不是用于排序的)。

答案 27 :(得分:0)

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 

答案 28 :(得分:0)

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)

答案 29 :(得分:-2)

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)

答案 30 :(得分:-7)

如果你有一个词典,例如:

not_ordered_dict = {5 : "5555", 9 : "9999", 1 : "1111"}

ordered_dict = {}

for key in sorted(not_ordered_dict):
    ordered_dict[key] = not_ordered_dict[key]