【问题标题】:Comparing slices in python比较python中的切片
【发布时间】:2017-06-15 10:35:38
【问题描述】:

dir()检查Python中的slice类,我发现它有__le____lt__的属性。确实,我看到以下代码有效:

slice(1, 2) < slice(3, 4)
# True

但是,我看不到这个比较实现了哪个逻辑,也看不到它的用例。谁能指点我?

我不是在问元组比较。即使 slice 和 tuple 以相同的方式进行比较,我认为这不会使我的问题重复。更重要的是,我还询问了切片比较的可能用例,建议的副本没有给出。

【问题讨论】:

  • 这不是重复的。我问的是切片,而不是元组。

标签: python slice


【解决方案1】:

查看slice的源代码,发现比较是先将两个对象转换成(start, stop, step)元组,然后比较这些元组:

https://github.com/python/cpython/blob/6cca5c8459cc439cb050010ffa762a03859d3051/Objects/sliceobject.c#L598

关于用例,我不确定作者的意图。我确实注意到,除了相等之外,似乎没有任何比较单元测试:

https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Lib/test/test_slice.py#L87

【讨论】:

    【解决方案2】:

    比较元组:(1, 2) &lt; (3, 4) 返回True,因为(1, 2) comes before (3, 4)

    但是,(1, 2) &lt; (0, 4) 返回False,因为(1, 2) comes after (0, 4)

    注意:&lt;&gt; 不是指smaller thangreater than,而是is beforeis after

    因此,换句话说,您正在比较哪个在前,哪个在之后。

    一些“奇怪”的案例(或者,&lt;&gt; 中的误导性案例):

    (1, 2) &lt; (3, 4, 5) 返回True,因为第一个元组的缺失值将等于操作的nil 值,在这种情况下为零。或者你可以认为(1, 2) come before (3, 4, 5)

    还有:

    (0, 1) &lt; (1, 0) 将返回True,因为(0, 1) comes before (1, 0)

    另一种情况:

    (0, 1, 20000) &lt; (0, 3, 1) 将返回True,因为(0, 1, 20000) comes before (0, 3, 1)

    slicelist 甚至 strings 的逻辑相同。

    欲了解更多信息,请访问answer

    【讨论】:

    • 关于您的“小于”评论,我相信 lt 和 le 代表小于和小于或等于。你确认了吗?
    • 是的,我确认。 __lt__ 的行为与 &lt; 相同。 &lt;=__le__ 也是如此。
    • 和__lt__,所以它确实意味着“小于”(在python中),不是吗?
    • 对于tuplesstringslists 将其视为comes before or comes after 而不是smaller and greater,否则您将面临一些奇怪的情况。但是,&lt; ccalls __lt__ 并且这种特殊方法对其数据的行为有所不同
    【解决方案3】:

    Python data model 只提到切片对象具有三个只读属性和一个方法。它没有提到切片的任何其他属性。

    正如@NPE 所提到的,CPython 实现确实provides 是切片对象的比较,它只是将slice 视为(start, end, step) 的元组。我用一个小的 Python 程序对其进行了检查,证实了这一点:

    vals = []
    for a in range(-5, 5):
        for b in range(-5, 5):
            for c in range(-5, 5):
                vals.append((a, b, c))
    for x in vals:
        for y in vals:
            assert (slice(*x) < slice(*y)) == (x < y)
    

    但是,这看起来像是一个非标准扩展。例如,Jython 也实现了切片的比较,但方式不同。此外,它看起来像implements 比较所有可能的对象对,方法是通过它们的ids 比较相同类型的对象,这会传播到切片。

    因此,Jython 中的切片顺序是不确定的。例如,以下 sn-p 在我的系统上使用 Jython 打印 True True 和使用 CPython 打印 True False

    print(slice(1, 2) < slice(1, 3))
    print(slice(1, 3) < slice(1, 2))
    

    总结:__lt__ 是在 CPython 中实现的,原因不明,但在文档中的任何地方都没有描述,其他实现可能不仅表现不同,而且“不正确”(在 mathematical sense 中)。因此,不应该比较切片的不等式。

    【讨论】:

      猜你喜欢
      • 2016-11-19
      • 2014-07-15
      • 2018-10-31
      • 2016-03-22
      • 2021-12-23
      • 2015-08-11
      • 1970-01-01
      • 2021-12-23
      • 2016-02-15
      相关资源
      最近更新 更多