Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I don't understand slicing with negative bounds in Python. How is this supposed to work?

Tags:

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.

like image 859
jtbradle Avatar asked Jan 29 '09 19:01

jtbradle


2 Answers

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.

like image 69
Lawrence Johnston Avatar answered Nov 10 '22 22:11

Lawrence Johnston


>>> l = ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz&']  # I want a string up to 'def' from 'vwx', all in between # from 'vwx' so -2;to 'def' just before 'abc' so -9; backwards all so -1. >>> l[-2:-9:-1] ['vwx', 'stu', 'pqr', 'mno', 'jkl', 'ghi', 'def']  # For the same 'vwx' 7 to 'def' just before 'abc' 0, backwards all -1 >>> l[7:0:-1] ['vwx', 'stu', 'pqr', 'mno', 'jkl', 'ghi', 'def'] 

Please do not become listless about list.

  1. Write the first element first. You can use positive or negative index for that. I am lazy so I use positive, one stroke less (below 7, or -3 for the start).
  2. Index of the element just before where you want to stop. Again, you can use positive or negative index for that (below 2 or -8 for stop).
  3. Here sign matters; of course - for backwards; value of stride you know. Stride is a 'vector' with both magnitude and direction (below -1, backwards all).

    l = [0,1,2,3,4,5,6,7,8,9] l[7:2:-1], l[-3:2:-1], [-3:-8:-1],l[7:-8:-1] 

    All result in [7, 6, 5, 4, 3].

like image 24
Rathinavelu Muthaliar Avatar answered Nov 11 '22 00:11

Rathinavelu Muthaliar