【问题标题】:Does ordered dict return keys in order too?有序 dict 是否也按顺序返回键?
【发布时间】:2016-04-05 13:44:18
【问题描述】:

例如:

my_dict = OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

如果获取密钥的操作,即my_dict.keys()my_dict.iterkeys() 完成,是否保证返回: ['apple','banana','orange','pear']?

这在文档中没有明确提及。

【问题讨论】:

  • 是的。 “OrderedDict - 添加了记住订单条目的 dict 子类”
  • @AndreyT 我知道这些项目,或者迭代,我的问题特别是关于 .keys() 或 .values() 方法
  • @DhruvPathak:是什么让你认为他们不会?键值对是条目。遍历键、值或项目都必须使用相同的顺序。如果情况并非如此,那将是非常令人惊讶,并且必须明确记录为例外。文档中没有这样的例外。
  • @DhruvPathak documentation 暗示了这一点:“OrderedDict 对象之间的相等性测试是顺序敏感的,并且实现为 list(od1.items())==list(od2 .items())。OrderedDict 对象和其他 Mapping 对象之间的相等性测试与常规字典一样对顺序不敏感。这允许在使用常规字典的任何地方替换 OrderedDict 对象。"
  • @DhruvPathak:该异常是一个错误;在文档或代码中。

标签: python


【解决方案1】:

是的,所有次迭代都保证使用相同的顺序。

如果他们不这样做,那将是一个非常大的例外,必须明确记录。该文档不包含此类例外。

您可以随时查看implementation,从模块文档顶部明确链接。您会注意到,所有方法实现都直接或通过iter(self)list(self) 使用self 上的迭代;所有这些都由OrderedDict.__iter__ 方法提供,该方法按顺序生成键:

def __iter__(self):
    'od.__iter__() <==> iter(od)'
    # Traverse the linked list in order.
    root = self.__root
    curr = root[1]                                  # start at the first node
    while curr is not root:
        yield curr[2]                               # yield the curr[KEY]
        curr = curr[1]                              # move to next node

例如,OrderedDict.values() 方法使用这些键映射到值:

def values(self):
    'od.values() -> list of values in od'
    return [self[key] for key in self]

【讨论】:

    【解决方案2】:

    简短回答:是的

    更长的答案:

    键(以及值)方法的实现基于“按顺序遍历链表”的__iter__ 方法。

        def keys(self):
            return list(self)
    
        def values(self):
            return [self[key] for key in self]
    

    您可以查看documentation中链接的source code

    【讨论】:

      【解决方案3】:

      是的,OrderedDict 将按顺序返回密钥。然而值得一提的是,the keys views compare order insensitive 这有点令人惊讶。

      这是 __iter__ 的 2.7 reference python implementation.keys.iterkeys 方法都将委托给:

      def __iter__(self):
          'od.__iter__() <==> iter(od)'
          # Traverse the linked list in order.
          root = self.__root
          curr = root[1]                                  # start at the first node
          while curr is not root:
              yield curr[2]                               # yield the curr[KEY]
              curr = curr[1]                              # move to next node
      

      self.__root 只是一个列表。

      注意: 实际实现是在 C 代码中。

      【讨论】:

      • 我在 Python 2 中没有看到 OrderedDict 的 C 实现。只有 Python 3 有加速版本。
      猜你喜欢
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多