Python反转字典项的顺序

5
假设我有一个字典:
d = {3: 'three', 2: 'two', 1: 'one'}

我希望重新排列这个字典的顺序,使得它的顺序是:
d = {1: 'one', 2: 'two', 3: 'three'}

我想到了像列表的reverse()函数那样的东西,但它不起作用。感谢您提前回答!

3个回答

14

自 Python 3.8 及以上版本,items 视图可以反向迭代,因此您只需执行以下操作:

d = dict(reversed(d.items()))

在3.7和3.6版本中,他们还没有实现dictdict视图上的__reversed__issue33462: reversible dict),因此请使用支持反向迭代的中间listtuple
d = {3: 'three', 2: 'two', 1: 'one'}
d = dict(reversed(list(d.items())))

在Python 3.6之前,你需要使用collections.OrderedDict(对于输入和输出都是如此)才能达到所需的结果。普通的dict在CPython 3.6之前不保留任何顺序(作为实现细节),在Python 3.7中则成为语言保证。

2

在Python 3.6之前,标准的Python字典没有顺序并且不能保证顺序。这正是创建OrderedDict的原因。

如果你的字典是一个OrderedDict,你可以通过以下方式将其反转:

reversed_dict = OrderedDict(reversed(list(your_ordered_dict.items())))
import collections

mydict = collections.OrderedDict()
mydict['1'] = 'one'
mydict['2'] = 'two'
mydict['3'] = 'three'

collections.OrderedDict(reversed(list(mydict.items())))

2
实际上,从3.6版本开始(CPython/PyPy实现细节)和3.7版本(作为语言保证),普通的dict是按插入顺序排序的,就像OrderedDict一样。OrderedDict提供了一些额外的API来操作顺序,但对于简单的反转操作,您不需要它。 - ShadowRanger
你为什么认为这是错误的?这里有一个演示,证明它是有效的:https://repl.it/repls/ExtraneousAllFormula - Bradd
@Bradd:错误的部分在于这个答案声称dict总是无序的(而现代CPython已经有序超过两年了)。 - ShadowRanger

1
另一个直接的解决方案是,在Python v3.7及以上版本中保证可行:
d = {'A':'a', 'B':'b', 'C':'c', 'D':'d'}
dr = {k: d[k] for k in reversed(d)}

print(dr)

输出:

{'D': 'd', 'C': 'c', 'B': 'b', 'A': 'a'}

请注意,反转字典仍被视为与其未反转的原始版本相等,即:
(d == dr) == True

作为对某人点赞的回应,我很好奇哪种解决方案实际上更快。
像往常一样,这取决于情况。将包含10,000个项目的字典反转10,000次,使用listreversed的解决方案更快。但是,将包含1,000,000个项目的字典反转100次(即总共反转字典中相同数量的项目,只是起始字典更大),则使用理解方式更快-读者需要找到确切的翻转点。如果您处理大型字典,则可能需要对性能进行基准测试。
from random import randint
from timeit import timeit


def f1(d):
    return dict(reversed(list(d.items())))


def f2(d):
    return {k: d[k] for k in reversed(d)}


def compare(n):
    d = {i: randint(1, 100) for i in range(n)}
    print(timeit(lambda: f1(d), number=100000000 // n))
    print(timeit(lambda: f2(d), number=100000000 // n))


compare(10000)
compare(1000000)

结果(一次运行,典型结果):

4.1554735
4.7047593
8.750093200000002
6.7306311

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接