【问题标题】:How to know if a Python type has a concept of order? What is a sequence, really?如何知道 Python 类型是否有顺序的概念?什么是序列,真的吗?
【发布时间】:2013-11-29 03:56:58
【问题描述】:

让我有点惊讶的是,Python 中的 OrderedDict 不是序列类型。它有顺序的概念,但不是序列。

Python docs

有七种序列类型:字符串、Unicode 字符串、列表、 元组、字节数组、缓冲区和 xrange 对象。

对于其他容器,请参阅内置的 dict 和 set 类,以及 收藏模块。 ...大多数序列类型支持以下 操作....序列类型也支持比较。

那些对应于__contains____add__的操作用于连接、__getitem__与整数(在range(len(foo))中)、__len____min____slice__indexcount__lt__等实现比较。

OrderedDicts 实现了其中一些方法,但没有实现其他方法,可能是因为通过键(如在 dict 中)或按顺序(如在 index 中)访问项目的语法糖是相同的。

我知道如果有东西实现了__iter__,我可以循环遍历它。我怎么能确定某样东西是否有订单?我以为这就是“序列”的意思,第 n 项始终是第 n 项。

【问题讨论】:

    标签: python types sequences


    【解决方案1】:

    在鸭子打字的世界里,这是一个难题。

    sequences and mapping 都使用 __getitem__() 来访问项目,分别使用内部索引和键。寻找 __getitem__() 方法的可用性并不能区分它们,您需要查看该方法的实际作用。

    对于 dict,无法知道 __getitem__() 的整数参数是索引还是键,因此它始终以映射样式工作。

    因此,我认为 dict 根本不是序列,即使它支持迭代。同样适用于套装。

    查看collections.abc.Sequence 基类可能是最好的测试。对于自定义类型,只需确保它们派生自此基类即可。

    【讨论】:

      【解决方案2】:

      issubclass(list, collections.abc.Sequence)

      请注意,这仅适用于内置类型。

      【讨论】:

      • 我当然也对自定义类型感兴趣。
      • 这也适用于用户定义的类型,前提是作者费心将所述类型设为collections.abc.Sequence 的(实际或虚拟)子类。
      【解决方案3】:

      这个想法是索引。 列表示例:

      >>> ['a', 'b', 'c'][1]          # get element with index 1
      'b'
      >>> ['a', 'b', 'c'].index('b')  # what is the (first) index of 'b'?
      1
      

      现在用字符串:

      >>> 'abc'[1]
      'b'
      >>> 'abc'.index('b')
      1
      

      现在使用有序字典:

      >>> from collections import OrderedDict
      >>> od = OrderedDict(zip(['cat', 'dog'], ['meow', 'auuu']))
      >>> od[1]
      (...)
      KeyError: 1
      >>> od.index('dog')
      AttributeError: 'OrderedDict' object has no attribute 'index'
      

      所以 OrderedDict 保留了添加项目的顺序,以便可以以相同的顺序对其进行迭代,但不能在其上使用索引。

      【讨论】:

        猜你喜欢
        • 2023-02-04
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-10
        • 1970-01-01
        • 2020-12-25
        相关资源
        最近更新 更多