# Understanding slice notation

Viewed : 47 times

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.

python list slice iterable

Nov 17

It's pretty simple really:

``````a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array``````

There is also the `step` value, which can be used with any of the above:

``a[start:stop:step] # start through not past stop, by step``

The key point to remember is that the `:stop` the value represents the first value that is not in the selected slice. So, the difference between `stop` and `start` is the number of elements selected (if `step` is 1, the default).

The other feature is that `start` or `stop` maybe a negative number, which means it counts from the end of the array instead of the beginning. So:

``````a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items``````

Similarly, `step` maybe a negative number:

``````a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed``````

Python is kind to the programmer if there are fewer items than you ask for. For example, if you ask for `a[:-2]` and `a` only contains one element, you get an empty list instead of an error. Sometimes you would prefer the error, so you have to be aware that this may happen.

### Relation to `slice()` object

The slicing operator `[]` is actually being used in the above code with a `slice()` object using the `:` notation (which is only valid within `[]`), i.e.:

``a[start:stop:step]``

is equivalent to:

``a[slice(start, stop, step)]``

Slice objects also behave slightly differently depending on the number of arguments, similarly to `range()`, i.e. both `slice(stop)` and `slice(start, stop[, step])` are supported. To skip specifying a given argument, one might use `None`, so that e.g. `a[start:]` is equivalent to `a[slice(start, None)]` or `a[::-1]` is equivalent to `a[slice(None, None, -1)]`.

While the `:`-based notation is very helpful for simple slicing, the explicit use of `slice()` objects simplify the programmatic generation of slicing.

#### Python slice notation

• Understanding Python's slice notation (this blog post)
• Understanding Python's slice assignment

### Basic syntax

Python's slice notation is used to return a list or a portion of a list. The basic syntax is as follows:

``[start_at:stop_before:step]``

Where `start_at` is the index of the first item to be returned (included), `stop_before` is the index of the element before which to stop (not included) and `step` is the stride between any two items.

All three of the arguments are optional, meaning you can omit any of them. For example:

``````nums = [1, 2, 3, 4, 5]

nums[1:4]     # [2, 3, 4]   (start at 0, stop before 4)
nums[2:]      # [3, 4, 5]   (start at 0, stop at end of list)
nums[:3]      # [1, 2, 3]   (start at 0, stop before 3)
nums[1:4:2]   # [2, 4]      (start at 1, stop before 4, every 2nd element)
nums[2::2]    # [3, 5]      (start at 2, stop at end of list, every 2nd element)
nums[:3:2]    # [1, 3]      (start at 0, stop before 3, every 2nd element)
nums[::2]     # [1, 3, 5]   (start at 0, stop at end of list, every 2nd element)
nums[::]      # [1, 2, 3, 4, 5] (start at 0, stop at end of list)``````

As you can probably tell from the examples above, the default values are `start_at = 0`, `stop_before = len(nums)`, `step = 1`.

An idiomatic way to shallow clone a list would be using `[:]` (e.g. `nums_clone = nums[:]`).

### Negative values

All three of the arguments also accept negative values. For `start_at` and `stop_before`, a negative value means counting from the end of the list instead of counting from the start. For example `-1` would represent the last element, `-2` the second last element etc. For example:

``````nums = [1, 2, 3, 4, 5]

nums[1:-2]    # [2, 3]      (start at 1, stop before 2nd to last)
nums[-3:-1]   # [3, 4]      (start at 3rd to last, stop before last)``````

A negative `step` means that the list is sliced in reverse (from end to start). This also means that `start_at` should be greater than `stop_before` and that `stop_before` in the context of a reverse stride is more like `stop_after` if you are looking at the list non-reversed. For example:

``````nums = [1, 2, 3, 4, 5]

nums[::-1]    # [5, 4, 3, 2, 1]   (reversed)
nums[4:1:-1]  # [5, 4, 3]   (reversed, start at 4, stop after 1)
nums[-1:1:-2] # [5, 3]      (reversed, start at last, stop after 1, every 2nd)``````

### Empty slices

Bear in mind that slice notation is very forgiving, so you'll get an empty list if the arguments' values are out of the list's range. For example:

``````nums = [1, 2, 3, 4, 5]

nums[6:8]     # []
nums[:-10]    # []``````

And a couple of things that weren't immediately obvious to me when I first saw the slicing syntax:

``````>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]``````

Easy way to reverse sequences!

And if you wanted, for some reason, every second item in the reversed sequence:

``````>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]``````

``mylist[X:Y]``