Comparing slices in python

时间:2017-06-15 10:35:38

标签: python slice

Inspecting the slice class in Python with dir(), I see that it has attributes __le__ and __lt__. Indeed I saw that the following code works:

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

However, I cannot see which logic is implemented for this comparison, nor its usecase. Can anyone point me to that?

I am not asking about tuple comparison. Even if slice and tuple are compared the same way, I don't think this makes my question a duplicate. What's more, I also asked for a possible usecase of slice comparison, which the suggested duplicate does not give.

3 个答案:

答案 0 :(得分:3)

查看slice的源代码,可以看出比较是通过首先将两个对象转换为(start, stop, step)元组,然后比较这些元组来实现的:

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

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

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

答案 1 :(得分:2)

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

但是,(1, 2) < (0, 4)会返回False,因为(1, 2) comes after (0, 4)

NB: <>并不代表smaller thangreater than,而是is before和{{} 1}}。

因此,换句话说,您将重新制作之前即将发生的事物。

有些&#34;奇数&#34;案例(或is after<内的误导性案例):

>返回(1, 2) < (3, 4, 5),因为第一个元组的缺失值将等于操作的True值,在这种情况下为零。或者您可以将其视为nil

(1, 2) come before (3, 4, 5)将返回(0, 1) < (1, 0),因为True

另一个案例:

(0, 1) comes before (1, 0)将返回(0, 1, 20000) < (0, 3, 1),因为True

(0, 1, 20000) comes before (0, 3, 1)slice甚至list的逻辑相同。

有关更多信息,请访问此answer

答案 2 :(得分:2)

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也实现了切片的比较,但是以不同的方式。此外,它通过比较相同类型的对象id来传播到切片,看起来像implements对所有可能的对象对进行比较。

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

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

总结:__lt__在CPython中实现是出于某些不明原因,但在文档中没有任何描述,其他实现可能不仅表现不同,而且“不正确”#34; (在mathematical sense中)。因此,不应该将切片与不等式进行比较。