【问题标题】:Python reverse dictionary items orderPython反向字典项目顺序
【发布时间】: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


    【解决方案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
    

    为了回应有人支持此评论,我很想知道哪种解决方案实际上更快。

    像往常一样,这取决于。在项目上使用 listreversed 的解决方案将 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
    

    【讨论】:

      【解决方案2】:

      从 Python 3.8 及以上版本开始,项目视图可以反向迭代,所以你可以这样做:

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

      在 3.7 和 3.6 上,他们还没有开始在 dictdict 视图 (issue33462: reversible dict) 上实现 __reversed__,所以使用中间的 listtuple,它们确实支持反转迭代:

      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(作为语言保证)之前没有保留任何顺序。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 实际上,从 3.6(CPython/PyPy 实现细节)和 3.7(作为语言保证)开始,纯 dict 是插入顺序的,就像 OrderedDict 一样。 OrderedDict 提供了一些额外的 API 来操作订单,但您不需要它来进行简单的反转。
        • 是什么让您认为这是错误的?这是一个演示它的工作原理:repl.it/repls/ExtraneousAllFormula
        • @Bradd:当这个答案声称dicts 总是无序时,错误的部分又回来了(现在它们已经在现代 CPython 上订购了两年多了)。
        猜你喜欢
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-21
        • 2016-01-31
        • 1970-01-01
        • 2011-02-16
        相关资源
        最近更新 更多