tags:

views:

228

answers:

5

I am a newbie to Python and have come across the following example in my book that is not explained very well. Here is my print out from the interpreter:

>>> s = 'spam'
>>> s[:-1]
'spa'

Why does slicing with no beginning bound and a '-1' return every element except the last one? Is calling s[0:-1] logically the same as calling s[:-1]? They both return the same result. But I'm not sure what python is doing exactly. Any help would be greatly appreciated.

+12  A: 

Yes, calling s[0:-1] is exactly the same as calling s[:-1].

Using a negative number as an index in python returns the nth element from the right-hand side of the list (as opposed to the usual left-hand side).

so if you have a list as so:

myList = ['a', 'b', 'c', 'd', 'e']
print myList[-1] # prints 'e'

the print statement will print "e".

Once you understand that (which you may already, it's not entirely clear if that's one of the things you're confused about or not) we can start talking about slicing.

I'm going to assume you understand the basics of a slice along the lines of myList[2, 4] (which will return ['c', 'd']) and jump straight into the slicing notation where one side is left blank.

As you suspected in your post, myList[:index] is exactly the same as myList[0:index].

This is also works the other way around, by the way... myList[index:] is the same as myList[index:len(myList)] and will return a list of all the elements from the list starting at index and going till the end (e.g. print myList[2:] will print ['c', 'd', 'e']).

As a third note, you can even do print myList[:] where no index is indicated, which will basically return a copy of the entire list (equivalent to myList[0:len(myList)], returns ['a', 'b', 'c', 'd', 'e']). This might be useful if you think myList is going to change at some point but you want to keep a copy of it in its current state.

If you're not already doing it I find just messing around in a Python interpreter a whole bunch a big help towards understanding these things. I recommend IPython.

Lawrence Johnston
Thanks! That explains it all.
jtbradle
Glad I could help:).
Lawrence Johnston
@Lawrence: in the 2nd paragraph after the code block, mylist[2, 4] should be myList[2:4]. (Sorry, I don't have enough rep to edit.)
Pourquoi Litytestdata
@Pourquoi Litytestdata: Good call on the typo, it's fixed now.
Lawrence Johnston
+1  A: 

Yes, calling s[0:-1] is logically the same thing as s[:-1] since slicing is best defined as:

[beginning_index:ending_index]

Python allows you to omit 0 as this allows your code to more terse.

Andrew Hare
+4  A: 

I could try to explain here, but I'll direct you to the excellent Mark Pilgrim's book:

http://diveintopython.org/getting_to_know_python/lists.html

Tiago
+1  A: 

Negative indices are counted from the end, so s[:-1] is equivalent to s[:len(s)-1] and s[-1] is the last element, for example.

MovEaxEsp
+2  A: 

The crucial point is that python indices should be thought of as pointers to the spaces between the entries in a list, rather than to the elements themselves. Hence, 0 points to the beginning, 1 to between the first and second, ... and n to between the nth and (n+1)st.

Thus l[1:2] gives you a list containing just element l[1] since it gives you everything between the two pointers.

Similarly, negative indices point in between elements, but this time counting from the back, so -1 points between the last element and the next-to-last, so [0:-1] refers to a block of items not including that last one.

As syntactic sugar, you can leave off 0 from the beginning or, in effect, the end, so l[n:] refers to everything from l[n] to the end (if n>=len(l) then it returns the empty list).

Andrew Jaffe
"Thus l[1:2] gives you just element l[1]" - l[1:2] returns a list that contains only element l[1]. This is different than just element l[1]. You could edit that not to confuse readers.
Abgan
l[n:] refers to an empty list - one 'behind last element'. This one also could be corrected :-)
Abgan
(Actually, for l[n:] I didn't mean n=len(l), but you're right, it's not clear... fixed both.
Andrew Jaffe