# Bug in string.find

Sat Sep 3 04:29:06 CEST 2005

```Terry Reedy wrote:
>
>>Fredrik Lundh wrote:
>>
>>>
>>>>The problem with negative index's are that positive index's are zero
>>>>based, but negative index's are 1 based.  Which leads to a non
>>>>symmetrical situations.
>>>
>>>indices point to the "gap" between items, not to the items themselves.
>>
>>So how do I express a -0?
>
>
> You just did ;-) but I probably do not know what you mean.

b[-1:] = ['Z']    # replaces last item
b[-1:-0] = ['Z']  # this doesn't work

If you are using negative index slices, you need to check for end
conditions because you can't address the end of the slice in a
sequential/numerical way.

b = list('abcdefg')
for x in range(-len(b),-1):
print b[x:x+2]

['a', 'b']
['b', 'c']
['c', 'd']
['d', 'e']
['e', 'f']
[]

b = list('abcdefg')
for x in range(-len(b),-1):
if x<-2:
print b[x:x+2]
else:
print b[x:]

['a', 'b']
['b', 'c']
['c', 'd']
['d', 'e']
['e', 'f']
['f', 'g']

>> Which should point to the gap after the last  item.
>
> The slice index of the gap after the last item is len(seq).
>
>
>>>straight indexing returns the item just to the right of the given gap
>>>(this is
>>>what gives you the perceived assymmetry), slices return all items
>>>between
>>>the given gaps.
>>
>>If this were symmetrical, then positive index's would return the value
>>to the right and negative index's would return the value to the left.
>
> As I posted before (but perhaps it arrived after you sent this), one number
> indexing rounds down, introducing a slight asymmetry.

I didn't see that one, but I agree.  Single index's are asymmetric,
positive slices with two index's are again symetric, negative slices
with negative strides or steps are again asymmetric.

>>Have you looked at negative steps?  They also are not symmetrical.
>
> ???

print a[4:1:-1]    #  6|g| 5|f| 4|e| 3|d| 2|c| 1|b| 0|a| ?
-> edc

print a[-3:-6:-1]  # -1|g|-2|f|-3|e|-4|d|-5|c|-6|b|-7|a|-8|
-> edc

# special case '::'
print a[6::-1]     #  6|g| 5|f| 4|e| 3|d| 2|c| 1|b| 0|a| ?
-> gfedcba

print a[-1:-8:-1]  # -1|g|-2|f|-3|e|-4|d|-5|c|-6|b|-7|a|-8
-> gfedcba

>>All of the following get the center 'd' from the string.
>>
>>a = 'abcdefg'
>>print a[3]         # d   4 gaps from beginning
>>print a[-4]        # d   5 gaps from end
>
> It is 3 and 4 gaps *from* the left and right end to the left side of the
> 'd'.  You can also see the asymmetry as coming from rounding 3.5 and -3.5
> down to 3 and down to -4.

Since single indexing only refers to existing items and aren't used to
insert between items, this still works even with the slight asymmetry.

>>print a[3:4]       # d
>>print a[-4:-3]     # d
>
> These are is symmetric, as we claimed.

Yes, no problem here except for addressing the -0th (end gap) position
without special casing to either a positive index or a[-n:].

>>print a[3:2:-1]    # d   These are symetric?!
>>print a[-4:-5:-1]  # d
>>print a[3:-5:-1]   # d
>>print a[-4:2:-1]   # d
>
> The pattern seems to be: left-gap-index : farther-to-left-index : -1 is
> somehow equivalent to left:right, but I never paid much attention to
> strides and don't know the full rule.

a[start:stop:-1]
a[stop:start]        # exchange index's
a.reverse()          # reverse string

a[4:1:-1]    #  6 |g| 5 |f| 4 |e| 3 |d| 2 |c| 1 |b| 0 |a| ?
a[1:4]       #  ? |a| 0 |b| 1 |c| 2 |d| 3 |e| 4 |f| 5 |g| 6
a.reverse()  # -> edc

Notice the index's are 1 less than with positive strides.

> Stride slices are really a different subject from two-gap slicing.  They
> were introduced in the early years of Python specificly and only for
> Numerical Python.  The rules were those needed specificly for Numerical
> Python arrays.  They was made valid for general sequence use only a few
> years ago.  I would say that they are only for careful mid-level to expert
> use by those who actually need them for their code.

I'd like to see those use case's.  I have a feeling there are probably
better ways to do it now.

Doing a quick search in python24/lib, there are only two places that use
a negative step or stride value to reverse a sequence.

---------- PICKLE.PY
return binary[::-1]
ashex = _binascii.hexlify(data[::-1])

I don't think people would miss negative strides much if they were
removed. Replacing these case's with reverse() methods shouldn't be that
difficult.

Cheers,
Ron

> Terry J. Reedy

```