# [Tutor] Counting a string backwards

C W tmrsg11 at gmail.com
Sun May 28 22:34:36 EDT 2017

```Wow, that's the best explanation I've seen so far, now it's gonna stick
with me!

Thank you!

On Sun, May 28, 2017 at 10:00 PM, Steven D'Aprano <steve at pearwood.info>
wrote:

> On Sun, May 28, 2017 at 01:58:22PM -0400, C W wrote:
> > Dear Python list,
> >
> > I am having trouble understanding the following.
> [...]
>
>
> The way to think about string indexing and slicing is that the index
> positions mark *between* the characters. Take your string:
>
>     Machine learning is awesome!
>
> For brevity, I'll just use the first word:
>
>     Machine
>
> Imagine slicing it between the characters. I'll mark the cuts with a
> vertical bar:
>
>     |M|a|c|h|i|n|e|
>
> and add indexes. The indexes will only line correctly if you use a
> monspaced or fixed width font like Courier, otherwise things may not
> line up correctly.
>
>     |M|a|c|h|i|n|e|
>     0 1 2 3 4 5 6 7
>
> Here they are again starting from the right, I've spread things out a
> bit to fit in the minus signs:
>
>    |M  |a  |c  |h  |i  |n  |e  |
>    -7  -6  -5  -4  -3  -2  -1  0
>
> Notice that 0 gets used twice. Of course, that's impossible, because it
> would be ambiguous. If you give 0 as an index, how does Python know
> whether you mean 0 at the start or 0 or the end? So the simple rule
> Python uses is that 0 *always* means the start.
>
> When you give a single index, Python always uses the character
> immediately to the right of the cut:
>
> s = "Machine"
> s[0]
> => returns "M"
>
> s[-1]
> => returns "e"
>
> s[7]
> => raises an exception, because there is no character to the right
>
> When you give two indexes, using slice notation, Python returns the
> characters BETWEEN those cuts:
>
> s[0:7]
> => returns "Machine"
>
> s[1:-1]
> => returns "achin"
>
> Because 0 always means the start of the string, how do you slice to the
> end? You can use the length of the string (in this case, 7) or you can
> leave the ending position blank, and it defaults to the length of the
> string:
>
> s[1:]  # means the same as [1:len(s)]
>
> You can leave the starting position blank too, it defaults to 0:
>
> s[:]  # means the same as [0:len(s)]
>
> So remember that slices always cut *between* the index positions.
>
>
> Things get complicated when you include a step (or stride), especially
> when the step is negative. For step sizes other than 1, it is
> probably best to think of looping over the string:
>
> py> s = "Nobody expects the Spanish Inquisition!"
> py> s[-1:1:-2]
> '!otsun snp h tex db'
>
> is somewhat like:
>
> for i in range(len(s)-1, 1, -2):
>     print s[i]
>
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
```