【问题标题】:python: iterate over dictionary sorted by keypython:遍历按键排序的字典
【发布时间】:2013-05-18 14:06:19
【问题描述】:

我有一本 Python 字典

steps = {1:"value1", 5:"value2", 2:"value3"}

我需要遍历这个按键排序。

我试过了:

x = sorted(steps, key=lambda key: steps[key])

但是这些值已经从 x 中消失了。

【问题讨论】:

    标签: python sorting dictionary


    【解决方案1】:

    我需要遍历这个是按键排序的顺序。

    我认为lambdas 在这里有点矫枉过正,试试这个:

    >>> steps = {1:"val1", 5:"val2", 2:"val3"}
    >>>
    >>> for key in sorted(steps):
    ...     print steps[key]
    ...
    val1
    val3
    val2
    

    【讨论】:

    • 如果键是字符串,但我需要将其排序为 int 怎么办?
    • sorted(steps) 优于 sorted(steps.keys())
    • 我知道这是一篇很老的帖子,但我在搜索其他内容时遇到了这个问题,我想指出:for key,value in sorted(steps): print valuefor key in sorted(steps): print steps[key] 快得多
    • @DaveLeBlanc:对于答案中定义的步骤for key,value in sorted(steps): print value 给出TypeError: 'int' object is not iterable - 你的意思是for key,value in sorted(steps.iteritems()): print value
    • Python 3:for key, value in sorted(steps.items()):.
    【解决方案2】:

    您需要遍历 steps.items(),因为遍历 dict 只会返回其键。

    >>> x = sorted(steps.items())
    >>> x
    [(1, 'value1'), (2, 'value3'), (5, 'value2')]
    

    遍历排序的键:

    >>> for key in sorted(steps):
    ...     # use steps[keys] to get the value
    

    【讨论】:

    • 那么我该如何迭代它,比如 iteritems 之类的?
    • @user984003 你不能对字典进行排序,你只能得到排序后的键、值或项目的列表。
    • @AshwiniChaudhary 对于sorted,您根本不需要key,字典键一定是唯一的,所以sorted(steps.items()) 工作正常
    【解决方案3】:

    您还可以使用 Python 的多种 SortedDict 容器类型之一。这些类型自动维护按键顺序排序的字典。看看sortedcontainers 模块,它是纯 Python 和快速 C 实现。有一个 performance comparison 可以对其他几个实现进行相互基准测试。

    在你的情况下,你会使用:

    from sortedcontainers import SortedDict
    steps = SortedDict({1:"value1", 5:"value2", 2:"value3"})
    
    # Then iterate the items:
    
    for key, value in steps.items():
        print key, value
    
    # Or iterate the values:
    
    for value in steps.values():
        print value
    

    键/值/项目的迭代按排序键顺序自动工作。

    【讨论】:

      【解决方案4】:

      如果您的键不是整数,而是应该被解析为整数的字符串:

      steps = {'1':'value1', '10': 'value0', '5':'value2', '2':'value3'}
      

      您可以使用与您的解决方案类似的东西:

      for key in sorted(steps, key=lambda key: int(key)):
          print(key, steps[key])
      
      1
      2
      5
      10
      

      【讨论】:

        【解决方案5】:

        就像 Zagorulkin Dmitry 指出的那样,您不应该将 lambda 传递给排序函数。排序功能的默认行为是作用于键。

        steps = {1:"val1", 5:"val2", 2:"val3"}
        
        for key in sorted(steps):
           print steps[key]
        ...
        val1
        val3
        val2
        

        但是,将 lambda 传递给排序函数并不是一个更好的小好处操作(即“过度杀伤”),但它实际上是不受欢迎的。它使代码的可读性降低并且速度也变慢,特别是如果您要将其应用于非常大的字典或多次调用时。除了在(键,值)对方面使排序目标更明确之外,使用它没有任何好处。以下时间显示了您在指定 lambda 时获得的性能影响。

        steps = {randint(0, 100000): randint(0, 100000) for _ in range(100000) } # random dict
        
        %%timeit 
        sort_list = [value for _, value in sorted(steps.items(), key=lambda item: item[0])]
        1 loops, best of 3: 241 ms per loop
        
        %%timeit 
        sort_list = [steps[k] for k in sorted(steps, key=lambda k: k)]
        1 loops, best of 3: 196 ms per loop
        
        %%timeit
        sort_list = [ steps[key] for key in sorted(steps) ]
        10 loops, best of 3: 106 ms per loop
        

        【讨论】:

          【解决方案6】:

          根据您的用例,保存已排序的字典可能是一种选择。有关详细信息,请参阅 pythons OrderedDict。如果要将键排序为整数,则必须将它们转换为整数。这样做的最佳时机取决于您的用例。

          【讨论】: