Python Slice Notation Guide

Python Slice Notation Guide

Explain Python's slice notation

The term slicing in programming usually refers to obtaining a substring, sub-tuple, or sublist from a string, tuple, or list respectively. 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.

In short, the colons (:) in subscript notation make slice notation - which has the optional arguments, start, stop, step:

sequence[start:stop:step]

Important Definitions

To begin with, let's define a few terms:

start
the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.
stop
the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.
step
the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

And recall, there are defaults for start, stop, and step, so to access the defaults, simply leave out the argument.

Mostly used variations
s[start:end]
s[start:]
s[:end]
Step-related variations
s[:end:step]
s[start::step]
s[::step]
Make a copy
s[:]

example:

mylist[X:Y]
X is the index of the first element you want.
Y is the index of the first element you don't want.

Another Definition

We work with sequence indexes. But there exist another way how to look on python slicing with positive step.
One way to remember how slices work is to think of the indices as pointing between characters, with the left or right edge of the first/last character marked as :. Table below show this situation.

Examples

We use this table for slice explanation. You can see list and slices indexes for list a=[1,2,3,4,5,6]

Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.

Index from rear:    -6  -5  -4  -3  -2  -1      a=[1,2,3,4,5,6]    a[1:]==[2,3,4,5,6]
Index from front:    0   1   2   3   4   5      len(a)==6          a[:5]==[1,2,3,4,5]
                   +---+---+---+---+---+---+    a[0]==1            a[:-2]==[1,2,3,4]
                   | 1 | 2 | 3 | 4 | 5 | 6 |    a[5]==6            a[1:2]==[2]
                   +---+---+---+---+---+---+    a[-1]==6           a[1:-1]==[2,3,4,5]
Slice from front:  :   1   2   3   4   5   :    a[-2]==5           a[1:-2]==[2,3,4]
Slice from rear:   :  -5  -4  -3  -2  -1   :
                                                b=a[:]
                                                b==[1,2,3,4,5,6] (shallow copy of a)
>>> a=[1,2,3,4,5,6]

>>> a[0:4]    # first 4 items
[1, 2, 3, 4]

>>> a[:4]     # first 4 items
[1, 2, 3, 4]

>>> a[1:4]
[2, 3, 4]

>>> a[1:2]
[2]

>>> a[1:]     # all items without first
[2, 3, 4, 5, 6]

>>> a[0:-1]   # all items withou last
[1, 2, 3, 4, 5]

>>> a[:5]
[1, 2, 3, 4, 5]

>>> a[-3:]    # last 3 items
[4, 5, 6]

>>> a[:-2]    # all items without last two
[1, 2, 3, 4]

>>> a[1:-1]
[2, 3, 4, 5]

>>> a[1:-2]
[2, 3, 4]

examples with positive steps:

>>> b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> b[0::2]
[1, 3, 5, 7, 9]

>>> b[0::3]
[1, 4, 7, 10]

>>> b[0::4]
[1, 5, 9]

>>> b[0:-2:2]
[1, 3, 5, 7]

When step is negative, the defaults for start and stop change

By default, when the step argument is empty (or None), it is assigned to +1.
But you can pass in a negative integer, and the list (or most other standard slicables) will be sliced from the end to the beginning.
Thus a negative slice will change the defaults for start and stop! The default then for start is -1 and stop is calculated as -(len(sequence) + 1).

Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.

Index from rear:    -6  -5  -4  -3  -2  -1      a=[1,2,3,4,5,6]    a[1:]==[2,3,4,5,6]
Index from front:    0   1   2   3   4   5      len(a)==6          a[:5]==[1,2,3,4,5]
                   +---+---+---+---+---+---+    a[0]==1            a[:-2]==[1,2,3,4]
                   | 1 | 2 | 3 | 4 | 5 | 6 |    a[5]==6            a[1:2]==[2]
                   +---+---+---+---+---+---+    a[-1]==6           a[1:-1]==[2,3,4,5]
Slice from front:  :   1   2   3   4   5   :    a[-2]==5           a[1:-2]==[2,3,4]
Slice from rear:   :  -5  -4  -3  -2  -1   :
                                                b=a[:]
                                                b==[1,2,3,4,5,6] (shallow copy of a)
Understanding index assignment is very important:
In forward direction, starts at 0 and ends at len(sequence) - 1
In backward direction, starts at -1 and ends at -(len(sequence) + 1)

examples:

a = [1, 2, 3, 4, 5, 6]

a[::-1]        # reverse list    
[6, 5, 4, 3, 2, 1]

a[-1::-1]      # reverse list
[6, 5, 4, 3, 2, 1]

a[:-7:-1]     # reverse list  
[6, 5, 4, 3, 2, 1]

a[-1:-7:-1]   # reverse list
[6, 5, 4, 3, 2, 1]

a[::-2]
[6, 4, 2]

a[-2::-2]
[5, 3, 1]

a[-1:-5:-2] 
[6, 4]

Interesting Python Slices

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

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
Slice first n and last m items

You can specify both positive and negative indices at the same time.

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
print(L[2:-5])
# Prints ['c', 'd']
Modify Multiple List Values

You can modify multiple list items at once with slice assignment. This assignment replaces the specified slice of a list with the items of assigned iterable.

# Modify multiple list items
L = ['a', 'b', 'c', 'd', 'e']
L[1:4] = [1, 2, 3]
print(L)
# Prints ['a', 1, 2, 3, 'e']
# Replace multiple elements in place of a single element
L = ['a', 'b', 'c', 'd', 'e']
L[1:2] = [1, 2, 3]
print(L)
# Prints ['a', 1, 2, 3, 'c', 'd', 'e']
Insert Multiple List Items

You can insert items into a list without replacing anything. Simply specify a zero-length slice.

# Insert at the start
L = ['a', 'b', 'c']
L[:0] = [1, 2, 3]
print(L)
# Prints [1, 2, 3, 'a', 'b', 'c']

# Insert at the end
L = ['a', 'b', 'c']
L[len(L):] = [1, 2, 3]
print(L)
# Prints ['a', 'b', 'c', 1, 2, 3]

You can insert items into the middle of list by keeping both the start and stop indices of the slice same.

# Insert in the middle
L = ['a', 'b', 'c']
L[1:1] = [1, 2, 3]
print(L)
# Prints ['a', 1, 2, 3, 'b', 'c']
Delete Multiple List Items

You can delete multiple items out of the middle of a list by assigning the appropriate slice to an empty list.

L = ['a', 'b', 'c', 'd', 'e']
L[1:5] = []
print(L)
# Prints ['a']

You can also use the del statement with the same slice.

L = ['a', 'b', 'c', 'd', 'e']
del L[1:5]
print(L)
# Prints ['a']

SUBSCRIBE FOR NEW ARTICLES

@
comments powered by Disqus