简体   繁体   English

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

[英]How do I sort a dictionary by key?

How do I sort a dictionary by its keys?如何按字典的键对字典进行排序?

Example input:示例输入:

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

Desired output:所需的 output:

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

Note: for Python 3.7+, see this answer注意:对于 Python 3.7+,请参阅此答案

Standard Python dictionaries are unordered (until Python 3.7).标准 Python 字典是无序的(直到 Python 3.7)。 Even if you sorted the (key,value) pairs, you wouldn't be able to store them in a dict in a way that would preserve the ordering.即使您对 (key,value) 对进行了排序,您也无法以保留顺序的方式将它们存储在dict中。

The easiest way is to use OrderedDict , which remembers the order in which the elements have been inserted:最简单的方法是使用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)])

Never mind the way od is printed out;没关系od的打印方式; it'll work as expected:它会按预期工作:

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蟒蛇 3

For Python 3 users, one needs to use the .items() instead of .iteritems() :对于 Python 3 用户,需要使用.items()而不是.iteritems()

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

Dictionaries themselves do not have ordered items as such, should you want to print them etc to some order, here are some examples:字典本身没有这样的订购项目,如果您想按某种顺序打印它们等,这里有一些例子:

In Python 2.4 and above:在 Python 2.4 及更高版本中:

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

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

gives:给出:

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

(Python below 2.4:) (Python 2.4 以下:)

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

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

For CPython/PyPy 3.6, and any Python 3.7 or higher, this is easily done with:对于 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}

From Python's collections library documentation :来自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)])

There are a number of Python modules that provide dictionary implementations which automatically maintain the keys in sorted order.有许多 Python 模块提供字典实现,这些实现自动按排序顺序维护键。 Consider the sortedcontainers module which is pure-Python and fast-as-C implementations.考虑sortedcontainers模块,它是纯 Python 和 fast-as-C 实现。 There is also a performance comparison with other popular options benchmarked against one another.还与其他流行的选项进行了性能比较,以彼此为基准。

Using an ordered dict is an inadequate solution if you need to constantly add and remove key/value pairs while also iterating.如果您需要在迭代的同时不断添加和删除键/值对,则使用有序 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)]

The SortedDict type also supports indexed location lookups and deletion which isn't possible with the built-in dict type. SortedDict 类型还支持索引位置查找和删除,这是内置 dict 类型无法实现的。

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

Simply:简单地:

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

for k,v in sd:
    print k, v

Output:输出:

1 89
2 3
3 0
4 5

Python dictionary was unordered before Python 3.6. Python 字典在 Python 3.6 之前是无序的。 In CPython implementation of Python 3.6, dictionary keeps the insertion order.在 Python 3.6 的 CPython 实现中,字典保持插入顺序。 From Python 3.7, this will become a language feature.从 Python 3.7 开始,这将成为一种语言特性。

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

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, eg Python 3.5).这个新实现的顺序保留方面被认为是一个实现细节,不应依赖(这可能会在未来发生变化,但在更改语言规范之前,希望在几个版本中使用该语言的这个新 dict 实现为所有当前和未来的 Python 实现强制要求保持顺序的语义;这也有助于保持与随机迭代顺序仍然有效的旧版本语言的向后兼容性,例如 Python 3.5)。

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

Performing list(d) on a dictionary returns a list of all the keys used in the dictionary, in insertion order (if you want it sorted, just use sorted(d) instead).对字典执行 list(d)以插入顺序返回字典中使用的所有键的列表(如果要对其进行排序,只需使用 sorted(d) 代替)。

So unlike previous versions, you can sort a dict after Python 3.6/3.7.因此与以前的版本不同,您可以在 Python 3.6/3.7 之后对 dict 进行排序。 If you want to sort a nested dict including the sub-dict inside, you can do:如果要对包含子字典的嵌套字典进行排序,可以执行以下操作:

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 https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb

As others have mentioned, dictionaries are inherently unordered.正如其他人所提到的,字典本质上是无序的。 However, if the issue is merely displaying dictionaries in an ordered fashion, you can override the __str__ method in a dictionary subclass, and use this dictionary class rather than the builtin dict .但是,如果问题只是以有序的方式显示字典,您可以覆盖字典子类中的__str__方法,并使用此字典类而不是内置的dict Eg.例如。

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}

Note, this changes nothing about how the keys are stored, the order they will come back when you iterate over them etc, just how they're displayed with print or at the python console.请注意,这不会改变密钥的存储方式、迭代它们时它们返回的顺序等,只是它们在print或 python 控制台中的显示方式。

Found another way:找到了另一种方式:

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

upd:更新:
1. this also sorts nested objects (thanks @DanielF). 1. 这也对嵌套对象进行排序(感谢@DanielF)。
2. python dictionaries are unordered therefore this is sutable for print or assign to str only. 2. python 字典是无序的,因此这仅适用于打印或分配给 str。

In Python 3.在 Python 3 中。

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

gives

1 89
2 3
3 0
4 5

An easy way to do this:一个简单的方法来做到这一点:

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} 

There are plenty of answers here already showcasing popular ways to sort a Python dictionary.这里有很多答案已经展示了对 Python 字典进行排序的流行方法。 I thought I'd add a few more less-obvious ways for those coming here from Google looking for non-standard ideas.我想我会为那些从谷歌来这里寻找非标准想法的人添加一些不太明显的方法。

Sample Dictionary: d = {2: 'c', 1: 'b', 0: 'a', 3: 'd'}示例字典: d = {2: 'c', 1: 'b', 0: 'a', 3: 'd'}

Dictionary Comprehension字典理解

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

Using Lambdas使用 Lambda

Sorting isn't always intended to order strictly in ascending or descending order.排序并不总是严格按照升序或降序排序。 For more conditional sorting, use the above method combined with lamdas:更多条件排序,结合lamdas使用上述方法:

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

More Examples更多示例

This thread is already full enough of good examples.这个线程已经有足够的好例子了。 For some more examples, as well as edge-cases and oddities check out this article on sorting dictionaries in Python.有关更多示例,以及边缘情况和奇怪之处,请查看这篇关于在 Python 中排序字典的文章。

You can create a new dictionary by sorting the current dictionary by key as per your question.您可以根据您的问题通过按键对当前字典进行排序来创建新字典。

This is your dictionary这是你的字典

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

Create a new dictionary d1 by sorting this d using lambda function通过使用 lambda 函数对该 d 进行排序来创建一个新字典 d1

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

d1 should be {1: 89, 2: 3, 3: 0, 4: 5}, sorted based on keys in d. d1 应该是 {1:89, 2:3, 3:0, 4:5},根据 d 中的键排序。

Here I found some simplest solution to sort the python dict by key using pprint .在这里,我找到了一些最简单的解决方案,可以使用pprint按键对 python dict 进行排序。 eg.例如。

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

but while using pprint it will return sorted dict但是在使用 pprint 时,它将返回排序的字典

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

There is an easy way to sort a dictionary.有一种简单的方法可以对字典进行排序。

According to your question,根据你的问题,

The solution is :解决方案是:

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

(Where c,is the name of your dictionary.) (其中 c 是您的字典的名称。)

This program gives the following output:该程序给出以下输出:

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

like u wanted.就像你想要的那样。

Another example is:另一个例子是:

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

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

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

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

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

Gives the output:给出输出:

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

Hence by changing it into keys, values and items , you can print like what u wanted.Hope this helps!因此,通过将其更改为键、值和项目,您可以像您想要的那样打印。希望这会有所帮助!

A simple way I found to sort a dictionary is to create a new one, based on the sorted key:value items of the one you're trying to sort.我发现对字典进行排序的一种简单方法是创建一个新字典,基于已排序的键:您要排序的那个的值项。 If you want to sort dict = {} , retrieve all its items using the associated method, sort them using the sorted() function then create the new dictionary.如果要对dict = {}进行排序,请使用关联方法检索其所有项目,使用sorted()函数对它们进行排序,然后创建新字典。

Here's the code using dictionary comprehension :这是使用字典理解的代码:

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

Will generate exactly what you want:将生成您想要的内容:

 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}

But this is not the correct way to do this, because, It could show a distinct behavior with different dictionaries, which I have learned recently.但这不是执行此操作的正确方法,因为,它可以用不同的字典显示不同的行为,这是我最近学到的。 Hence perfect way has been suggested by Tim In the response of my Query which I am sharing here.因此,蒂姆在我在这里分享的查询的回复中提出了完美的方法。

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

Here is the performance of the suggested solutions:以下是建议解决方案的性能:

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)

As we see, Grant Jenks's solution is by far the fastest.正如我们所见, Grant Jenks 的解决方案是迄今为止最快的。

I think the easiest thing is to sort the dict by key and save the sorted key:value pair in a new dict.我认为最简单的方法是按键对字典进行排序并将排序后的键:值对保存在一个新的字典中。

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]

To make it clearer:为了更清楚:

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

I come up with single line dict sorting.我想出了单行字典排序。

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

Hope this will be helpful.希望这会有所帮助。

Python dicts are un-ordered. Python dicts 是无序的。 Usually, this is not a problem since the most common use case is to do a lookup.通常,这不是问题,因为最常见的用例是进行查找。

The simplest way to do what you want would be to create a collections.OrderedDict inserting the elements in sorted order.做你想做的最简单的方法是创建一个collections.OrderedDict以排序顺序插入元素。

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

If you need to iterated, as others above have suggested, the simplest way would be to iterate over sorted keys.如果您需要迭代,正如上面其他人所建议的那样,最简单的方法是迭代排序的键。 Examples-例子-

Print values sorted by 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

Get list of values sorted by keys:获取按键排序的值列表:

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

This function will sort any dictionary recursively by its key.此函数将按其键递归地对任何字典进行排序。 That is, if any value in the dictionary is also a dictionary, it too will be sorted by its key.也就是说,如果字典中的任何值也是字典,它也将按其键排序。 If you are running on CPython 3.6 or greater, than a simple change to use a dict rather than an OrderedDict can be made.如果您在 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)

Simplest solution is that you should get a list of dict key is sorted order and then iterate over dict.最简单的解决方案是你应该得到一个 dict 键的列表,然后按顺序遍历 dict。 For example例如

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]

Following will be the output (desending order)以下将是输出(降序)

e 30
b 13
d 4
c 2
a 1

For the way how question is formulated, the most answers here are answering it correctly.对于问题的表述方式,这里的大多数答案都是正确回答。

However, considering how the things should be really done, taking to acount decades and decades of computer science, it comes to my total suprise that there is actually only one answer here (from GrantJ user) suggesting usage of sorted associative containers (sortedcontainers) which sorts elements based on key at their insertions point.然而,考虑到事情应该如何真正完成,考虑到几十年和几十年的计算机科学,我完全感到惊讶的是,这里实际上只有一个答案(来自GrantJ用户)建议使用排序关联容器(排序容器)根据插入点处的键对元素进行排序。

That will avoid massive performance impact per each calling of sort(...) (at minimum O(N*log(N)) , where N is in number of elements (logically, this applies for all such solutions here which suggest to use the sort(...) ). Take to account that for all such solutions, the sort(...) will need to be called every time when colletion needs to be accessed as sorted AFTER it was modified by adding/removing elements ...这将避免每次调用sort(...)性能产生巨大影响(至少O(N*log(N)) ,其中N是元素的数量(从逻辑上讲,这适用于此处建议使用的所有此类解决方案sort(...) ). 考虑到对于所有此类解决方案,每次需要在通过添加/删除元素修改集合按排序方式访问集合时,都需要调用sort(...) 。 ..

Guys you are making things complicated ... it's really simple伙计们,你让事情变得复杂......这真的很简单

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

The output is:输出是:

{'A':2,'B':1,'C':3}
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)
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]}

A timing comparison of the two methods in 2.7 shows them to be virtually identical: 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 

Or use pandas ,或者使用pandas

Demo:演示:

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

Docs of this 这方面的文档

Documentation of whole pandas整个熊猫的文档

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)

Another pythonic approach would be 另一种pythonic方法是

def sort_dict(my_dict):
    return sorted(my_dict.items(), key=lambda x :x[1])


My suggestion is this as it allows you to sort a dict or keep a dict sorted as you are adding items and might need to add items in the future:我的建议是这样,因为它允许您在添加项目时对字典进行排序或保持字典排序,并且将来可能需要添加项目:

Build a dict from scratch as you go along.随着您的进行,从头开始构建一个dict Have a second data structure, a list, with your list of keys.有第二个数据结构,一个列表,其中包含您的键列表。 The bisect package has an insort function which allows inserting into a sorted list, or sort your list after completely populating your dict. bisect 包有一个 insort 函数,它允许插入一个排序的列表,或者在完全填充你的字典后对你的列表进行排序。 Now, when you iterate over your dict, you instead iterate over the list to access each key in an in-order fashion without worrying about the representation of the dict structure (which was not made for sorting).现在,当您遍历您的 dict 时,您改为遍历列表以按顺序访问每个键,而不用担心 dict 结构的表示(不是为排序而制作的)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM