【发布时间】:2019-09-18 13:45:07
【问题描述】:
假设我有一本字典:
d = {3: 'three', 2: 'two', 1: 'one'}
我想重新排列这本字典的顺序,使字典为:
d = {1: 'one', 2: 'two', 3: 'three'}
我在想类似reverse() 函数的列表,但那不起作用。提前感谢您的回答!
【问题讨论】:
标签: python python-3.x sorting dictionary reverse
假设我有一本字典:
d = {3: 'three', 2: 'two', 1: 'one'}
我想重新排列这本字典的顺序,使字典为:
d = {1: 'one', 2: 'two', 3: 'three'}
我在想类似reverse() 函数的列表,但那不起作用。提前感谢您的回答!
【问题讨论】:
标签: python python-3.x sorting dictionary reverse
另一个简单的解决方案,保证适用于 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
为了回应有人支持此评论,我很想知道哪种解决方案实际上更快。
像往常一样,这取决于。在项目上使用 list 和 reversed 的解决方案将 10,000 项字典反转 10,000 次更快。但是,将 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
【讨论】:
从 Python 3.8 及以上版本开始,项目视图可以反向迭代,所以你可以这样做:
d = dict(reversed(d.items()))
在 3.7 和 3.6 上,他们还没有开始在 dict 和 dict 视图 (issue33462: reversible dict) 上实现 __reversed__,所以使用中间的 list 或 tuple,它们确实支持反转迭代:
d = {3: 'three', 2: 'two', 1: 'one'}
d = dict(reversed(list(d.items())))
Pre-3.6,you'd need collections.OrderedDict(用于输入和输出)以达到预期的结果。 Plain dicts 在 CPython 3.6(作为实现细节)和 Python 3.7(作为语言保证)之前没有保留任何顺序。
【讨论】:
标准 Python 字典(Python 3.6 之前)没有顺序,也不保证顺序。这正是创建OrderedDict 的目的。
如果您的字典是 OrderedDict,您可以通过以下方式将其反转:
import collections
mydict = collections.OrderedDict()
mydict['1'] = 'one'
mydict['2'] = 'two'
mydict['3'] = 'three'
collections.OrderedDict(reversed(list(mydict.items())))
【讨论】:
dict 是插入顺序的,就像 OrderedDict 一样。 OrderedDict 提供了一些额外的 API 来操作订单,但您不需要它来进行简单的反转。
dicts 总是无序时,错误的部分又回来了(现在它们已经在现代 CPython 上订购了两年多了)。