I need a good explanation (references are a plus) on Python's slice notation.
To me, this notation needs a bit of picking up.
It looks extremely powerful, but I haven't quite got my head around it.
It's pretty simple really:
There is also the
The key point to remember is that the
The other feature is that
Python is kind to the programmer if there are fewer items than you ask for. For example, if you ask for
The Python tutorial talks about it (scroll down a bit until you get to the part about slicing).
The ASCII art diagram is helpful too for remembering how slices work:
Enumerating the possibilities allowed by the grammar:
Of course, if
Extended slicing (with commas and ellipses) are mostly used only by special data structures (like Numpy); the basic sequences don't support them.
And a couple of things that weren't immediately obvious to me when I first saw the slicing syntax:
Easy way to reverse sequences!
And if you wanted, for some reason, every second item in the reversed sequence:
I use the "an index points between elements" method of thinking about it myself, but one way of describing it which sometimes helps others get it is this:
X is the index of the first element you want.
After using it a bit I realise that the simplest description is that it is exactly the same as the arguments in a for loop...
any of them are optional
then the negative indexing just needs you to add the length of the string to the negative indices to understand it.
This works for me anyway...
The answers above don't discuss slice assignment:
This may also clarify the difference between slicing and indexing.
Found this great table at http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
This is just for some extra info... Consider the list below
Few other tricks for reversing the list:
See abc's answer above
I find it easier to remember how it's works, then I can figure out any specific start/stop/step combination.
It's instructive to understand
The thing to remember about negative step is that
Sequence slicing is same, except it first normalizes negative indexes, and can never go outside the sequence:
TODO: The code below had a bug with "never go outside the sequence" when abs(step)>1; I think I patched it to be correct, but it's hard to understand.
Don't worry about the
Normalizing negative indexes first allows start and/or stop to be counted from the end independently:
In Python 2.7
Slicing in Python
Understanding index assignment is very important.
When you say [a:b:c], you are saying depending on the sign of c (forward or backward), start at a and end at b (excluding element at bth index). Use the indexing rule above and remember you will only find elements in this range:
But this range continues in both directions infinitely:
If your choice of a, b, and c allows overlap with the range above as you traverse using rules for a,b,c above you will either get a list with elements (touched during traversal) or you will get an empty list.
One last thing: if a and b are equal, then also you get an empty list:
I hope this will help you to model the list in Python.
You can also use slice assignment to remove one or more elements from a list:
Python slicing notation:
The notation extends to (numpy) matrices and multidimensional arrays. For example, to slice entire columns you can use:
Slices hold references, not copies, of the array elements. If you want to make a separate copy an array, you can use
To get a certain piece of an iterable (like a list), here is an example:
In this example, a positive number for number 1 is how many components you take off the front. A negative number is the exact opposite, how many you keep from the end. A positive number for number 2 indicates how many components you intend to keep from the beginning, and a negative is how many you intend to take off from the end. This is somewhat counter intuitive, but you are correct in supposing that list slicing is extremely useful.
As a general rule, writing code with a lot of hardcoded index values leads to a readability and maintenance mess. For example, if you come back to the code a year later, you’ll look at it and wonder what you were thinking when you wrote it. The solution shown is simply a way of more clearly stating what your code is actually doing. In general, the built-in slice() creates a slice object that can be used anywhere a slice is allowed. For example:
If you have a slice instance s, you can get more information about it by looking at its s.start, s.stop, and s.step attributes, respectively. For example:
In short, the colons (
Python slicing is a computationally fast way to methodically access parts of your data. In my opinion, to be even an intermediate Python programmer, it's one aspect of the language that it is necessary to be familiar with.
To begin with, let's define a few terms:
How Indexing Works
You can make any of these positive or negative numbers. The meaning of the positive numbers is straightforward, but for negative numbers, just like indexes in Python, you count backwards from the end for the start and stop, and for the step, you simply decrement your index. This example is from the documentation's tutorial, but I've modified it slightly to indicate which item in a sequence each index references:
How Slicing Works
To use slice notation with a sequence that supports it, you must include at least one colon in the square brackets that follow the sequence (which actually implement the
Slice notation works like this:
And recall that there are defaults for start, stop, and step, so to access the defaults, simply leave out the argument.
Slice notation to get the last nine elements from a list (or any other sequence that supports it, like a string) would look like this:
When I see this, I read the part in the brackets as "9th from the end, to the end." (Actually, I abbreviate it mentally as "-9, on")
The full notation is
and to substitute the defaults (actually when
And clearing them is with:
(Python 3 gets a
Give your slices a descriptive name!
You may find it useful to separate forming the slice from passing it to the
However, you can't just assign some integers separated by colons to a variable. You need to use the slice object:
The second argument,
You can then pass the slice object to your sequence:
Since slices of Python lists create new objects in memory, another important function to be aware of is
The fact that list slices make a copy is a feature of lists themselves. If you're slicing advanced objects like a Pandas DataFrame, it may return a view on the original, and not a copy.
You can run this script and experiment with it, below is some samples that I got from the script.
When using a negative step, notice that the answer is shifted to the right by 1.
This is how I teach slices to newbies:
Understanding difference between indexing and slicing:
Wiki Python has this amazing picture which clearly distinguishes indexing and slicing.
It is a list with 6 elements in it. To understand slicing better, consider that list as a set of six boxes placed together. Each box has an alphabet in it.
Indexing is like dealing with the contents of box. You can check contents of any box. But You can't check contents of multiple boxes at once. You can even replace contents of the box. But You can't place 2 balls in 1 box or replace 2 balls at a time.
Slicing is like dealing with boxes itself. You can pickup first box and place it on another table. To pickup the box all You need to know is the position of beginning & ending of the box.
You can even pickup first 3 boxes or last 2 boxes or all boxes between 1 & 4. So, You can pick any set of boxes if You know beginning & ending. This positions are called start & stop positions.
The interesting thing is that You can replace multiple boxes at once. Also You can place multiple boxes where ever You like.
Slicing With Step:
Till now You have picked boxes continuously. But some times You need to pickup discretely. For example You can pickup every second box. You can even pickup every third box from the end. This value is called step size. This represents the gap between Your successive pickups. The step size should be positive if You are picking boxes from the beginning to end and vice versa.
How Python Figures Out Missing Parameters:
When slicing if You leave out any parameter, Python tries to figure it out automatically.
If You check source code of CPython, You will find a function called PySlice_GetIndicesEx which figures out indices to a slice for any given parameters. Here is the logical equivalent code in Python.
This function takes a Python object & optional parameters for slicing and returns start, stop, step & slice length for the requested slice.
This is the intelligence that is present behind slices. Since Python has inbuilt function called slice, You can pass some parameters & check how smartly it calculates missing parameters.
Note: This post is originally written in my blog http://www.avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html
My brain seems happy to accept that
But occasionally a doubt creeps in and my brain asks for reassurance that it does not contain the
In these moments I rely on this simple theorem:
This pretty property tells me that
Note that this theorem is true for any
1. Slice Notation
To make it simple, remember slice has only one form：
and here is how it works:
Another import thing: all
So possible variations are:
The above part explains the core features on how slice works, it will work on most occasions. However there can be pitfalls you should watch out, and this part explains them.
The very first thing confuses python learners is that index can be negative! Don't panic: negative index means count from backwards.
Make things more confusing is that
Negative step means iterate the array backwards: from end to start, with end index included, and start index excluded from result.
NOTE: when step is negative, the default value for
Out of range error?
Be surprised: slice does not raise IndexError when index is out of range!
If the index is out of range, python will try its best set the index to
Let's finish this answer with examples explains everything we have discussed:
The answers above don't discuss multi-dimentional array slicing which is possible using the famous numpy package:
Slicing also apply to multi-dimentional arrays.
The ":2" before comma operates on the first dimension and the "0:3:2" after the comma operates on the second dimension.
The below is the example of index of a string
slicing example: [start:end:step]
Below is the example usage
In Python, the most basic form for slicing is the following:
When slicing from start, you can omit the zero index, and when slicing to the end, you can omit the final index since it is redundant, so do not be verbose:
Negative integers are useful when doing offsets relative to the end of a collection:
It is possible to provide indices that are out of bounds when slicing such as:
Keep in mind that the result of slicing a collection is a whole new collection. In addition, when using slice notation in assignments, the length of the slice assignment do not need to be the same. The values before and after the assigned slice will be kept, and the collection will shrink or grow to contain the new values:
If you omit the start and end index, you will make a copy of the collection:
If the start and end indexes are omitted when performing an assignment operation, the entire content of the collection will be replaced with a copy of what is referenced:
Besides basic slicing, it is also possible to apply the following notation:
It is also possible to use negative integers for
However, using a negative value for
Most of the above answers clears about Slice notation.
Extended indexing syntax used for slicing is
More Slicing examples: 15 Extended Slices
Hehehe, it is kind of strange to see myself trying to provide a better and simpler explanation after 2600+ votes on what's been marked as the right answer from Grew Hewgill.
Here we go ...
In my opinion, you will understand and memorize better the Python string slicing notation if you look at it the following way (read on).
Let's work with the following string ...
For those who don't know, you can create any substring from
Coming from other programming languages, that's when the common sense gets compromised. What are x and y?
I had to sit down and run several scenarios in my quest for a memorization technique that will help me remember what x and y are and help me slice strings properly at the first attempt.
My conclusion is that x and y should be seen as the boundary indexes that are surrounding the strings that we want to extra. So we should see the expression as
Here is an example visualization of that ...
So all you have to do if to set index1 and index2 to the values that will surround the desired substring. For instance, to get the substring "cdefgh", you can use
Remember, we are setting the boundaries.
That trick works all the time and is easy to memorize.
Hopefuly this will help.
If you feel negative indices in slicing is bit "unnatural", here's very easy way to think about it: just replace negative index with len - index. So for example, replace -3 with