A Deep Dive of Working With Lists in Python: Indexing and Slicing

Accessing items in a list (and other iterables such as tuples and strings) is a fundamental ability for Python programmers, and many Python tools use similar indexing and slicing principles (e.g., NumPy Arraysand pandas DataFrames).

The term ‘indexing’ refers to the process of referring to an element of an iterable based on its position inside the iterable. Slicing an iterable involves extracting a subset of elements based on their indices.

Let’s start by making a list that we can play with using a list comprehension:

Indexing

The index operator ([]) is used to obtain a list element:

Because lists are “zero-indexed,” [0] returns the list’s zeroth (i.e., left-most) item, while [1] returns the one-th item (i.e., one item to the right of the zeroth item) because our list has nine elements ([0] through [8]), attempting to access my list[9] results in an IndexError: list index out of range because it is attempting to obtain the tenth element, which does not exist.

A negative number can also be used to index from the end of the list, where [-1] returns the last member. This is quite beneficial because it eliminates the need to programmatically determine the length of the iterable in order to interact with elements at the end. my_list indices and reverse indices are as follows:

Slicing

A slice is a collection of list items. A single slice of a list will always be made up of contiguous components. The format of slice notation is as follows:

Where start is the index of the first element to include in the slice, and stop is the index of the last item to exclude from the slice. So [‘b’, ‘c’, ‘d’, ‘e’] is returned by my_list[1:5]:

Starting from (or going to), the end of the list is indicated by leaving either slice border blank. For example:

The start/stop boundaries are set relative to their position from the end of the list when using a negative indexer. Thus my_list[-5:-2] produces [‘e’, ‘f’, ‘g’]:

The output of my_list[-2:-5] will be an empty list if it is indexed. An element must be at or to the right of the start boundary AND to the left of the stop boundary to be included in the slice. The slicer stops before putting any values into the slice because the -2 is already to the right of -5.

A for loop works in a similar way; the first loop has no output, whereas the second does:

Stepping

An optional third argument to the slicer specifies the interval at which elements are included in the slice. So [‘a’, ‘c’, ‘e’, ‘g’, ‘i’] is returned by my_list[::2]:

And [‘b’, ‘d’, ‘f’, ‘h’] is returned by my_list[1::2]:

Negative step values make the slicer iterate over the original list in the opposite direction:

List elements’ indexed positions do not change, but the order in which they are returned does. The start and stop limits are also flipped; thus, the start value should be the slice’s far rightmost point, and the stop value should be far to the left. So [‘f’, ‘e’] comes from my_list[5:3:-1]:

Similarly, my_list[-2:-5:-1] returns [‘h’,’g’,’f’]:

And [‘i’, ‘f’, ‘c’] comes from my list[-1:-8:-3]: 

Reference:

  • https://towardsdatascience.com/the-basics-of-indexing-and-slicing-python-lists-2d12c90a94cf