The nice thing about slices is that they either make sense, or they don’t. In any case it won’t matter. Python will give the sensible portion (sequence) if one can be got.
What that means is we can loosely validate the indices given in the slice using logical operators.
>>> def f(w, s, e): return w[w.find(s) + 1 : w.find(e) + 1 and w.find(e) or None] >>> f('xabcy', 'x', 'y') 'abc' >>> f('zabcy', 'x', 'y') 'zabc' >>> f('zabcn', 'x', 'y') 'zabcn' >>> f('abc', 'x', 'y') 'abc' >>>
This is really just a doodling, and may have edge cases. Testing required. On the surface, it looks to be quite solid.
Faulty slice indices will not raise an error (unless they are non-integer). They just might not work as expected.
w.find(s) + 1
This value we already understand, or at least the example it is taken from would suggest as much.
s is found ? return index then add 1
We wish to exclude the exact index from the slice.
s is not found ? return minus 1 then add 1
We wish to include the first element in the slice.
Both cases generate a valid slice index that meets our needs.
w.find(e) + 1 and w.find(e) or None
A little more obscure, though discernible.
w.find(e) + 1
This operand will generate a non-zero value, or zero. That value is unimportant, only evaluated for truthiness. Not found is
-1 so adding
1 will make that read as zero, which is falsy.
When the above is truthy, anding with the actual index will yield that index. If falsy, the yield is
[1, 2, 3, 4, 5][1:None] # [2, 3, 4, 5]
There are two ways to interpret that word. 1. to give way as in to allow another’s passage while we wait; or, 2. to generate as in crop yield.
Boolean expressions yield according to the second definition.