A specific example of my question is, \"How can I get \'3210\' in this example?\"
>>> foo = \'0123456\'
>>> foo[0:4]
\'0123\'
>>> foo[::-1]
\'6543210\'
>>>
If you're looking for something a little more human-readable than extended slice notation:
>>> foo = '0123456'
>>> ''.join(reversed(foo[0:4]))
'3210'
After reading the "technical documentation" (here) - specifically the sentence:
If either bound is negative, the sequence’s length is added to it.
I decided to try this, and it worked:
>>> foo = '0123456'
>>> foo[3:-1-len(foo):-1]
'3210'
>>>
So I think the best answer to programmatically determine the "end point" would be to provide a well named helper function that makes it clear that its arguments are always treated like positive offsets, maybe special_slice()
I think the clarity of this 'special' case is extremely important since lots of common and significant use cases depend on the default behavior of negative offsets (i.e. adding the length to them). Personally I frequently use a '-1' end point to mean: stop just before last element.
So, based on your comment:
... algorithm that works somewhat like as follows: foo[i:i-4:-1], and starts with a high 'i' and walks down.
I might make the following:
def slice_by_len(data, start, length, step=1):
end = start + length if step > 0 else start - length
if end < 0:
# Fix the negative offset to get what we really want
end -= len(data)
return data[start:end:step]
And then call it for each slice required:
foo_part = slice_by_len(foo, i, 4, -1)
The above could easily go in a loop over values of 'i'