测试整数是否是切片的索引值

时间:2019-02-22 20:44:58

标签: python slice

是否存在布尔函数来测试整数是否为slice对象中包含的索引值?是否不解包startstopstep参数?

3 in slice(1,6,2)

由于切片不可迭代而引发错误。

谓词应适用于任意None startstopstep参数。逻辑很简单,但是希望有一个内置的或包。

2 个答案:

答案 0 :(得分:5)

逻辑并没有您想象的那么直接,因为对于None停止或启动(取决于step的符号),这样做是没有意义的,因为您需要指定长度。

本质上,您要的是在range对象中进行遏制,该对象具有与切片相同的信息,但是是有效序列,并且支持快速遏制检查。 slice有一个indices方法可帮助进行转换,如果您提供了对切片感兴趣的序列的长度,则:

def in_slice(n, s, length):
    return n in range(*s.indices(length))

答案 1 :(得分:0)

如果您可以选择一个适当大小的范围,则可以对其应用切片并确定索引是否在该范围内。

对于正/无边界,这仅是具有足够大的范围来包含索引本身的问题:

i in range(i+1)[slice(start,stop,step)]

3 in range(7)[slice(1,6,2)] --> True

为了支持负边界(尤其是负起始),您需要确保从起始位置开始的索引偏移量是该步长的倍数,并且其大小足够小以包含索引。这是在假设存在包含索引的范围大小的假设下。否则,您必须自己提供范围大小:

def inSlice(i,s, size = None):
    if size is None:
        step  = s.step  or 1
        start = s.start or 0
        size  = size or i+1
        if step < 0 or start <= 0:
           size = (i-min(0,start))//step*step - int(s.stop is None)
    return  i in range(size)[s]

这将提供以下结果:

inSlice( 3 , slice(1, 6, 2) )           -->  True ( size = 4 )
inSlice( 37000216 , slice(10, 100000000, 3) )   -->  True ( size = 37000217 )
inSlice( 17 , slice(-100, 10, -3) )     -->  True ( size = 117 )
inSlice( 17 , slice(-100, -10, 3) )     -->  True ( size = 117 )
inSlice( 97 , slice(100, None, -3) )    -->  True ( size = 98 )
inSlice( 107 , slice(None, 100, -3) )   -->  True ( size = 108 )
inSlice( 97 , slice(-10, None, -3) )    -->  True ( size = 107 )