indexing in python

Indexing and Slicing in Python [Explained with Examples]

List and String are the most used iterable data types in Python. Accessing elements in a list, or characters in a string is a very important operation.

In Python, Indexing and slicing are the fundamental blocks to access elements of Iterable objects. In this article, we will learn indexing and slicing in Python in detail with examples.

Indexing in Python

Indexing is a way of accessing elements based on a sequence number. Following are a few examples of accessing things in real life.

  • Governments assign identification numbers to smaller geo locations on the bigger regions they belong to. It gives governments an option of easy access to their smaller geo-locations.
  • Schools and Colleges give their students a unique identification number based on the school joining academic year. With these numbers, students are easily accessed and identified within the school area.
  • Every Computer that connects to the internet is given an IP number for easy identification and access. Other Computers can access this computer with an IP number.

Similar to the above real-life use cases, In computer science also, We have different access patterns for different data structures.

  • In non-linear data structures like Tree, An element can be accessed from its parent node.
  • In the linear data structure LinkedList, A node can be accessed from its previous node’s next address field.

Unlike Tree and LinkedList, Python’s iterable types like list, string, and tuple support random access to elements based on their position or sequence number in the data type.

The following are a few important things about Indexing in Python:

Indexing - Things you must know:

1. Square brackets: Square brackets [] are used to access elements using index number from the iterable object.

2. Positive indexing: In positive indexing, index number range starts from 0 and ends at length of iterable minus 1.

3. Negative indexing: In negative indexing, index number range start from negative of length of iterable and ends at -1.

4. IndexError: When elements are accessed with a number from outside the range of index number, IndexError will be thrown. 

positive and negative indexing in python

We will go through the above properties of indexing one by one.

Square brackets

As in the below program, []- square brackets can be used to access elements from a list and string with a number.

employee_salaries = [100, 130, 110, 170, 150]
print(employee_salaries[0])

employee_name = 'Mbappe'
print(employee_name[0])

Output:

100
M

Positive indexing

In the Positive indexing approach, the index number starts at 0 and ends at the length of the list minus 1 (n-1).

For example:

employee_salaries = [140, 170, 190, 130, 180, 210]

print(employee_salaries[0])
print(employee_salaries[1])
print(employee_salaries[2])
print(employee_salaries[3])
print(employee_salaries[4])
print(employee_salaries[5])

Output:

140
170
190
130
180
210

Negative Indexing

In negative indexing, the last element’s index is -1 and the first element’s index is negative of the length of the list.

For Example: Note that the output is in the reverse order of the list elements.

employee_salaries = [140, 170, 190, 130, 180, 210]

print(employee_salaries[-1])
print(employee_salaries[-2])
print(employee_salaries[-3])
print(employee_salaries[-4])
print(employee_salaries[-5])
print(employee_salaries[-6])

Output:

210
180
130
190
170
140

IndexError

In both positive and negative approaches, When you try to access elements of indexable iterable with an outside index range number then you will end up in IndexError.

Example 1:

In the below code, the employee_salaries list of length 5 and in negative index range is from -5 to -1. Accessing an element with a -6 number from employee_salaries results in an IndexError.

employee_salaries = [100, 130, 110, 170, 150]
print(employee_salaries[-6])

Output:

Traceback (most recent call last):
  File "/home/user/Desktop/codethreads/python/index_test.py", line 2, in <module>
    print(employee_salaries[-6])
IndexError: list index out of range

Example 2:

In the below program, the employee_name string is of length 6 and the index range in positive indexing is 0 to 5. index number 6 will be out of range.

employee_name = 'Mbappe'
print(employee_name[6])
Traceback (most recent call last):
  File "/home/user/Desktop/codethreads/python/index_test.py", line 19, in <module>
    print(employee_name[6])
IndexError: string index out of range


Slicing in Python

As explained above, the indexing concept allows elements access via sequence numbers from the list. The Slicing allows us to retrieve the sublist of elements from the indexable iterable object.

The following are a few real-life examples of slicing:

  • Governments assign unique numbers to their smaller geo-locations and they can slice the sequence of unique numbers to assign them to one bigger region
  • Schools or colleges assign unique ids to students and they can slice these to form smaller classrooms within the school.
  • On the internet, every device is assigned an IP and these sequential IPs can be sliced to form a network.

Slice has the below properties to control the sublist’s elements and size.

  • start: An index from where the sublist starts.
  • stop: An index at a new sublist will end ( stop index is exclusive)
  • step: A number, which will be increased at each iteration
Slicing operation options:

Python has below two options for slicing operation.

1. Slicing operator: iterable[start:stop:step] - with the help of square brackets and colon(:).

2. Slice class: slice(start, stop, step) - slice class constructor has 3 parameters and step is an optional parameter.

Slicing algorithm

Both the slicing operator and slice class accept positive and negative numbers for start, stop, and step. The only exception is zero is not allowed for the step.

We can summarize the functioning of the slicing operation in the below 4 steps.

Step 1: Defaults Selection

  • step: The default value for step is 1.
  • start: The default value for start depends on the step. if step < 0 then length-1 else 0.
  • stop: The default value for stop also depends on the step. if step < -1 then 0 else length.
salaries = [100, 130, 110, 170, 150]

salaries[-3::]

In the above example, we have specified only the start index. So by default it takes stop as length and step as 1. The above statement becomes

salaries[-3:5:1]

Step 2: Remove range outliers

  • step: no changes to step
  • start: if start < -length then start = -length or if start > length then start = length -1.
  • stop: if stop < -length then then stop = -length or if stop > length then stop = length.
salaries = [100, 130, 110, 170, 150]

salaries[-8:10:1]

Here, since the given indexes are out of range, slicing operator will convert them to remove the outliers. It modifies the statements to below.

salaries[-5:5:1]

Step 3: Convert to normal positive Indices

  • step: no changes
  • start: if start < 0 then start = start + length
  • stop: if stop < -1 then stop = stop + length
salaries = [100, 130, 110, 170, 150]

salaries[-5:-3:1]

The next step is to convert negative index to positive ones. In the above example, -5 index will be converted to 0th index and -3 index changes to 2.

salaries[0:2:1]

Step 4: Iterate from start to stop with the given step

sample code:

new_list = []
for index in range(start, stop, step):
    new_list.append(source_list[index])

Slicing Code Examples

Example 1:

# length of s is 12
s = "abcdefghijkl"

# step will be 1 by default
res = s[0:10:]

print(res)

Output:

abcdefghij

Explanation:

  • Step 1: default value for the step is taken as 1 and no changes for start and stop.
    • step = 1, start = 0, and stop = 10
  • Step 2: No changes to start and stop in this step as they are in the range of (-length, length). step = 1, start = 0, and stop = 10.
  • Step 3: No changes as start >= 0 and stop >= -1. step = 1, start = 0, and stop = 10.
  • Step 4: iterates from start to stop with step increment and prints ‘abcdefghij’.

Example 2:

s = ‘abcdefghijkl’ and length is 12

s = "abcdefghijkl"
part = slice(None, None, -1)

print(s[part])

Output:

lkjihgfedcba

Explanation:

  • Step 1: Defaults selection – step = -1, start = 11, stop = 0
    • step = -1, no changes
    • start = 11, since step < 0
    • stop = 0, since step < 0
  • Step 2: Remove outlier indices – no changes as start and stop are in range(-length, length).
  • Step 3: Convert to normal indices – no changes since start>=0 and stop >= -1.
  • Step 4: iterate from 11 to -1 with the step as -1. range(11, -1, -1) will have 12 iterations.

Example 3:

s = ‘abcdefghijkl’ and length is 12

s = "abcdefghijkl"
part = slice(-1, -10, -1)
print(s[part])

Output:

lkjihgfed

Explanation:

  • Step 1: Defaults selection – no changes, all parameters are given. start = -1, stop = -10, and step = -1.
  • Step 2: Remove outlier indices – no changes, as start and stop are in range(-length, length). start = -1, stop = -10, and step = -1.
  • Step 3: Convert to normal indices. start = 11, stop = -10, and step = -1.
    • step = -1, no changes.
    • start = -1 + 12 = 11
    • stop = -10 + 12 = 2
  • Step 4: iterate from 11 to 2 with the step as -1. range(11, 2, -1) will have 9 iterations.

Errors to watch out for:

ValueError: slice step cannot be zero, will be raised when the step is passed as 0.


Indexing and slicing in NumPy

Numpy’s array also supports indexing and slicing just like Python’s list, string, and tuple.

Code Thread:

import numpy as np

np_array = np.array([100, 110, 130, 150, 170])

second_element = np_array[1]
part = np_array[2:4]

print(part)
print(second_element)

Output:

[130 150]
110


Indexing and slicing in Pandas

Pandas library primarily supports indexing with the below two methods.

  • loc() – for label-based indexing
  • iloc() – for position-based indexing

Code Thread for position-based indexing using pandas iloc():

import pandas as pd

l = [100, 110, 130, 150, 170]

df = pd.DataFrame(l, columns=['salaries'])
print(df)

print(df.iloc[1:])

Output:

   salaries
1       110
2       130
3       150
4       170

Thanks for reading the article. Hope you have understood things about indexing in Python along with the slicing concept. If you liked our explanation, follow us for more learning.

Frequently Asked Questions

  • How to find the index of an element in a list in Python?

    You can use the list.index(element) method to find the index of an element in a list in Python.

  • Does indexing start at 0 or 1 in Python?

    Python’s indexing starts from 0.

Leave a Comment

Your email address will not be published. Required fields are marked *