What is slicing and indexing in python explain with an example?

Table of contents:

    • Intro to Slicing in Python
      • Indexing
      • Slicing
      • What Are Slices in Python?
      • Conclusions of Slicing in Python tutorial

Intro to Slicing in Python

Slicing in Python is a feature that enables accessing parts of sequences like strings, tuples, and lists. You can also use them to modify or delete the items of mutable sequences such as lists. Slices can also be applied on third-party objects like NumPy arrays, as well as Pandas series and data frames.

Slicing enables writing clean, concise, and readable code.

This article shows how to access, modify, and delete items with indices and slices, as well as how to use the built-in class slice().

If you prefer video here is the Slicing in Python tutorial on youtube:

Indexing

You can access a single item of a Python sequence (such as string, tuple, or list) with the corresponding integer indices. Indices in Python are zero-based. This means the index 0 corresponds to the first (leftmost) item of a sequence, 1 to the second item, and so on.

Let’s create one string, one tuple, and one list to illustrate how to use indices:

>>> str_ = 'Python is awesome!'
>>> str_
'Python is awesome!'
>>> tuple_ = (1, 2, 4, 8, 16, 32, 64, 128)
>>> tuple_
(1, 2, 4, 8, 16, 32, 64, 128)
>>> list_ = [1, 2, 4, 8, 16, 32, 64, 128]
>>> list_
[1, 2, 4, 8, 16, 32, 64, 128]

Indices are provided inside the brackets, that is with the syntax sequence[index]:

>>> str_[0]
'P'
>>> str_[1]
'y'
>>> str_[4]
'o'
>>> tuple_[0]
1
>>> tuple_[1]
2
>>> tuple_[4]
16
>>> list_[0]
1
>>> list_[1]
2
>>> list_[4]
16

As you can see ‘P’ is the first character of the string ‘Python is awesome!’ and it corresponds to the index 0, ‘y’ is the second and has index 1 and so on.

It’s very similar to tuples and lists.

Python provides the possibility to use negative integer indices as well. This appears to be very useful in practice, especially when you want to access the last (rightmost) item of a sequence.

The index -1 corresponds to the last item, -2 to the second last, and so on:

>>> str_[-1]
'!'
>>> str_[-2]
'e'
>>> str_[-5]
's'
>>> tuple_[-1]
128
>>> tuple_[-2]
64
>>> tuple_[-5]
8
>>> list_[-1]
128
>>> list_[-2]
64
>>> list_[-5]
8

As you can see, the character ‘!’ is the last item in the string ‘Python is awesome!’ and it corresponds to the index -1. It also has the index 17, which is string_[17] returns ‘!’. The character ‘e’ takes place just in front of it and has the index -2 and 16.

Again, tuples and lists behave similarly.

You can use indices to modify the items of the mutable sequence. In Python, strings and tuples are immutable, but lists are mutable:

>>> list_[-1] = 100
>>> list_
[1, 2, 4, 8, 16, 32, 64, 100]

This example changes the last item of the list to 100. Since this list has eight items, you can also access the last item with the zero-based index 7, that is you can accomplish the same effect with the statement list_[7] = 100.

Slicing

Slicing in Python is similar to indexing but returns a sequence of items instead of a single item. The indices used for slicing are also zero-based.

There are two variants of the slicing syntax: sequence[start:stop] and sequence[start:stop:step]. This article explains both.

When you use the syntax sequence[start:stop], you’ll get the new sequence. It will start with the item that has the index start (inclusive) and end before the item with the index stop. In other words, the statement sequence[start:stop] returns the items sequence[start], sequence[stop-1], and all the items between them:

>>> str_[1:5]
'ytho'
>>> tuple_[2:4]
(4, 8)
>>> tuple_[2:3]
(4,)
>>> tuple_[2:2]
()

As you can see, the returning sequence can contain only one item when start + 1 == stop or it can be an empty sequence when start == stop.

When you omit start, the value 0 is taken, that is the resulting sequence starts at the beginning of the original:

>>> str_[:2]
'Py'
>>> tuple_[:4]
(1, 2, 4, 8)

If you omit to stop, the resulting sequence stops at the end of the original:

>>> str_[2:]
'thon is awesome!'
>>> tuple_[4:]
(16, 32, 64, 128)

Consistently, you can omit both start and stop:

>>> str_[:]
'Python is awesome!'
>>> tuple_[:]
(1, 2, 4, 8, 16, 32, 64, 128)
>>> list_[:]
[1, 2, 4, 8, 16, 32, 64, 100]

That’s how you get a shallow copy of a sequence.

It’s possible to apply negative values of start and stop similarly as with indices:

>>> str_[-8:]
'awesome!'
>>> tuple_[:-1]
(1, 2, 4, 8, 16, 32, 64)
>>> tuple_[-4:-2]
(8, 16)
>>> tuple_[3:5]
(8, 16)

In the case of tuple_, the value -4 — when counting backward from -1 — corresponds to the same item as the value 3 when counting forward from 0. It’s the same for the values 5 and -2. Again, the item that corresponds to the index stop isn’t included in the resulting sequence.

The syntax sequence[start:stop:step] is similar, but with few more details.

You can use a step to specify the step if you want to skip some items:

In this example, step is 2, so you start with the item that has the index 1 (the item 2), collect every second item, and stop before you reach the item with the index 5 (32). You take the item 2, skip 4, and take 8.

If the step is positive and you omit start, the resulting sequence again starts at the beginning of the original. If you omit to stop, the operation stops at the end of the original. However, if you omit a step, it’s considered as 1 and you get the same behavior as with the syntax sequence[start:stop]:

>>> tuple_[:6:2]
(1, 4, 16)
>>> tuple_[3::2]
(8, 32, 128)
>>> tuple_[1:5:]
(2, 4, 8, 16)

A negative value of step, in combination with a start greater than stop, can be used to collect items backward:

>>> tuple_[4:1:-1]
(16, 8, 4)
>>> tuple_[6:1:-2]
(64, 16, 4)

In the cases with negative step and omitted start, the resulting sequence starts at the end of the original. If you omit to stop, the operation stops at the beginning of the original:

>>> tuple_[:2:-1]
(128, 64, 32, 16, 8)
>>> tuple_[5::-1]
(32, 16, 8, 4, 2, 1)

These rules are conveniently applied to get the shallow copy of a sequence with the items in the reversed order by omitting both, start and stop:

>>> tuple_[::-1]
(128, 64, 32, 16, 8, 4, 2, 1)

You can use slices to modify the items of mutable sequences:

>>> list_[1:6:2]
[2, 8, 32]
>>> list_[1:6:2] = [20, 80, 320]
>>> list_
[1, 20, 4, 80, 16, 320, 64, 100]

In this example, the items with the indices 1, 3, and 5 are accessed and modified.

If you use the syntax sequence[start:stop], it’s possible to replace a part of a sequence with a smaller or larger one:

>>> list_[1:5]
[20, 4, 80, 16]
>>> list_[1:5] = [0, 0]
>>> list_
[1, 0, 0, 320, 64, 100]

In this example, four items are removed ([20, 4, 80, 16]) and two new ones ([0, 0]) are added instead.

Following this logic, you can delete parts of mutable sequences by replacing them with empty sequences like []:

>>> list_[1:3]
[0, 0]
>>> list_[1:3] = []
>>> list_
[1, 320, 64, 100]

It’s also possible to delete parts of sequences using slices in the del statement:

>>> list_[:2]
[1, 320]
>>> del list_[:2]
>>> list_
[64, 100]

So, there are two approaches to delete a part of a list. However, the latter seems more readable and easily understandable because using the del statement makes your intention (to delete something) obvious.

What Are Slices in Python?

The slices are the instances of the Python built-in class slice. You create them with the statement slice(start, stop, step). It’s possible to pass an instance of a slice instead of start:stop:step or start:stop:

>>> s = slice(1, 5, 2)
>>> s
slice(1, 5, 2)
>>> s.start, s.stop, s.step
(1, 5, 2)
>>> tuple_[s]
(2, 8)

Again, you can omit step and get the behavior of start:stop:

>>> s = slice(1, 5)
>>> s.start, s.stop, s.step
(1, 5, None)
>>> tuple_[s]
(2, 4, 8, 16)

If you pass a single argument, slice uses it as stop and behaves as :stop:

>>> s = slice(5)
>>> s.start, s.stop, s.step
(None, 5, None)
>>> tuple_[s]
(1, 2, 4, 8, 16)

You can manipulate slices inside functions and methods:

>>> def get_items_with_slice(sequence, start, stop, step):
...     return sequence[slice(start, stop, step)]
... 
>>> get_items_with_slice([1, 2, 4, 8, 16, 32, 64, 128], 1, 5, None)
[2, 4, 8, 16]

This function uses its own arguments to create a slice and passes it to get some data from a sequence.

Finally, here’s an example of how you can use slices in combination with the Python special method _getite_() to define a class whose instances can be used with the index notation:

>>> class C:
...     def __init__(self, *args):
...         self.__data = args
...     def __getitem__(self, index_or_slice):
...         print('index or slice:', index_or_slice)
...         return self.__data[index_or_slice]
... 
>>> x = C(1, 2, 4, 8, 16, 32, 128)
>>> x[4]
index or slice: 4
16
>>> x[1:5:2]
index or slice: slice(1, 5, 2)
(2, 8)

If you pass an integer to __getitem__(), it will behave as an index of self.__data. If you pass start:stop:step instead, __getitem__() actually obtains a slice object as an argument.

You can also use __setitem__() to modify data and __delitem__() to delete data, potentially combined with slices.

Conclusions of Slicing in Python tutorial

This article shows how slicing in python works. It is very powerful and useful when you need to extract items from sequences like strings, tuples, and lists. Also, some third-party objects such as NumPy arrays and Pandas series and data frames.

In python you can use slices inside functions and methods. If you want to define classes with the possibility to access, modify, or delete data with the instance[index_or_slice] notation, you should implement the special methods __getitem__(), __setitem__(), or __delitem__() and possibly apply python slices.

Thank you for reading!

Why you should learn Python?

What is scikit learn – introduction to popular machine learning and data science Python library

Python list – definition and usage

Radek Fabisiak was with the computers from his early days, remembers an orange screen with Win32, big floppy disks, and the sound of dial-up connecting to the internet. He has got experience in full-stack development by working for top IT companies like Microsoft. In the last years, in the core team of the Duomly, where as an addition to IT has got skills related to Online Marketing, SEO, Content Creation or building Online Business, now passing this knowledge to the Duomly’s audience.

More about Radek Fabisiak

If you liked it share and comment!

What is indexing and slicing in Python with example?

What are Indexing and Slicing? Indexing: Indexing is used to obtain individual elements. Slicing: Slicing is used to obtain a sequence of elements. Indexing and Slicing can be be done in Python Sequences types like list, string, tuple, range objects.

What is slicing in Python with example?

Definition and Usage. The slice() function returns a slice object. A slice object is used to specify how to slice a sequence. You can specify where to start the slicing, and where to end. You can also specify the step, which allows you to e.g. slice only every other item.

What is slicing and negative indexes in Python explain with example?

Negative Slicing in Python This means you can start slicing from the end of the sequence. Here the slicing starts at the index -4 which is the 4th last element of the list. The slicing ends at the last item, which is at the index -1. Also, the step size can be a negative value.

What is a slice index in Python?

The slice method in Python returns a slice object. This object contains a list of indices specified by a range. This slice object can be used to index relevant elements from the given array, list, or even from a tuple.