Testing if an index is in a slice
Bryan Olson
fakeaddress at nowhere.org
Sat Jan 3 17:53:12 EST 2009
ajaksu wrote:
> On Jan 1, 4:12 pm, mma... at gmx.net wrote:
>> I would like to check if an index is in a slice or not without
>> iterating over the slice.
>>
>> Something like:
>>
>>>>> isinslice(36, slice(None, 34, -1))
>> True
>
> I think it'd be feasible for slices that can be mapped to ranges[1],
> but slices are more flexible than that.
If we add a parameter for the length of the list to which the slice is
applied, then inslice() is well-defined.
I thought it would easy to write, but that was hours ago when I knew
less about Python slice indexing than I do now. And I thought I new a
bunch from writing a virtual slice class.
I'm leaning towards mmanns' idea that this should be built in. Handling
all the cases is remarkably tricky. Here's a verbose version, with a
little test:
def inslice(i, slc, length):
""" Would index i be part of slice slc of a list of len length?
"""
step = slc.step or 1
if step > 0:
if slc.start is None:
start = 0
elif slc.start >= 0:
start = slc.start
else:
start = max(0, length + slc.start)
if slc.stop is None:
stop = length
elif slc.stop >= 0:
stop = min(length, slc.stop)
else:
stop = length + slc.stop
return start <= i < stop and (i - start) % step == 0
else:
if slc.start is None:
start = length - 1
elif slc.start >= 0:
start = min(length - 1, slc.start)
else:
start = length + slc.start
if slc.stop is None:
stop = -1
elif slc.stop >= 0:
stop = slc.stop
else:
stop = max(-1, length + slc.stop)
return start >= i > stop and (start - i) % (-step) == 0
# test
for start in [None, 0, 1, -1, -3, 4]:
for stop in [None, 0, 1, -1, 3, -5]:
for step in [None, 1, -1, 2, -3]:
for n in [0, 1, 2, 3, 5, 11, 16]:
slc = slice(start, stop, step)
s1 = [i for i in range(-3, n + 5) if inslice(i, slc, n)]
s2 = sorted(range(n)[slc])
assert s1 == s2
--
--Bryan
More information about the Python-list
mailing list