How to slice Python List

The complete breakdown of the implementation of slice operations

As I studied the Python documentation to understand the implementation of slice operation on sequence types, it made me remember this quote my physics teacher in Highschool said one time when he was explaining how the equations of motion were derived.

If you understand how the equation is derived, you don't need to memorize the equation.

Understanding the implementation of slice operations will assist you with knowing the likely result to expect every time you perform any slice operation on a List in Python.

So what is a List?

A List is a sequence type, which means it is a collection of ordered items. it is the first of two ordered-collection data structures in Python.

And list slicing is a very important sequence operation that is used extensively in data analysis so having a good understanding of the different slice operations is necessary.

First, I want to introduce some parameters that will assist my explanation of the concepts I will discuss in this article.

I will be using \(s\) to illustrate a list object instance.

So anytime you see me use \(s\) in the article know that I'm referring to a list of items.

Also, I will be using \(len(s)\) to illustrate the total number of items in a list.

So anytime you see me use \(len(s)\) in the article, know that I'm referring to total number of items in list \(s\).

Now we know that \(s\) is a list and the total number of the items inside the list is \(len(s)\) (len() is an actual Python built-in function that returns the total number of items in a collection).

Note: Although in this article I will be using list slice operations for the demonstration of my understanding, these slice operations I'm about to explain are supported by most sequence types.

Let us get started!

Slice concept one

slice the item at index \(i\) of the list.

To slice the item at index \(i\) of \(s\) we use \(s[i]\).

Where \(i\) is either a positive or negative integer.

If \(i\) is a positive integer, the item that is sliced from \(s\) will be any item at index \(i\) from origin index \(0\).

In Python sequence types, the index of the first item is index \(0\)

Let's see the code example:

First, lets us create a list object instance to contain the collection of vowel letters.

# create a list object instance that contains vowel letters
vowels = ['a','e','i','o','u']

Now let us slice the item at index \(4\) of the vowels list.

# slice the item at index 4 of the vowels list
vowels[4]

The output of this slice operation is the letter 'u'.

This result is true because if we count the indexes of the items in the vowels list, starting from origin index \(0\), we will see that the letter 'u' is the item that is actually at index \(4\) of the vowels list.

** Recall that \(i\) can also be a negative integer**

Now If \(i\) is a negative integer, the slice output of the item at index \(i\) of \(s\) will be any item that is at index \(len(s) - | i |\).

So for example, if \(i = - 2\) and \(len(s) = 5\)

\(s[-2]\) will output any item in \(s\) at the index which is equal to the solution of

\(5 - 2\)

which is equal to index \(3\)

Let's see the code example:

First, let us compute the total number of items in the vowels list.

# compute the total number of items in the vowels list
len(vowels)

The output of len(vowels) is \(5\).

And this is so because len() is a Python function that counts the items of a sequence in arithmetic progression, starting its count with \(1\) for the first item it encounters in the sequence, and then constantly adding \(1\) to the count afterwards for every other item it encounters till it gets to the last item in the sequence.

Now let us slice the item at index \(-2\) of the vowels list.

# slice the item at  index -2 of the vowels list
vowels[-2]

The output of the slice operation is the letter 'o'.

And this result is true because if you count the indexes of items in the vowels list, starting your count from index \(0\) which is the index of the first item of the list, you will see that the letter 'o' is actually the item at index \(3\) of vowels list even though we used a negative integer to perform the slice operation.

What has happened is that when we use a negative index integer as \(i\), it means that we are counting the list items in reverse order starting from the end of the sequence.

In Python sequence types, when counting in reverse order from the end of the sequence, the index of the first item we count is \(-1\).

Slice concept 2

Slice all items from index \(i\) to index \(j\) of the list.

We continue with our illustration list \(s\).

To slice all items from index \(i\) to index \(j\) of \(s\) we use \(s[i:j]\)

The kind of slice will output all items from index \(i\) to before index \(j\) of a list (the item at index \(j\) of a list will not be included in the output).

Let's see the code example:

Let's slice all items from index \(1\) to index \(4\) of the vowels list.

# slice all items from index 1 to index 4
vowels[1:4]

The output of this slice operation is the letters 'e','i','o' (excluding the letter 'u' which is the item at index \(4\)).

There is more.

If we omit index \(i\) or use 'None', this slice operation will implicitly default to use index \(0\).

Let's see the code example

Let us slice the vowels list from an omitted start index to the end index \(4\).

# slice all items from an omitted start index to index 4 of the vowels list
vowels[:4]

The output of this slice operation is the letters 'a', 'e', 'i', 'o' which now includes the letter 'a' at index \(0\) but still excludes the letter at index \(4\).

Also if we omit the index \(j\) or use None , this slice operation will implicitly default to use len(s) in place of \(j\).

Let's see a code example

Let us slice the vowels list from the start index \(1\) to an omitted end index.

# slice the vowels list from the start index 1 to an omitted end index 
vowels[1:]

The output of this slice operation is the letters 'e', 'i', 'o', 'u'.

Now we can see that the letter 'u' which is at index \(4\) of the vowels list is included because the slice operation implicitly using the len(s) of the vowels list means that the value of the end index is now greater than the index of the last item in the list.

Lastly for this section, if i is greater than or equal to j, the output willl be empty.

Slice Concept 3

Slice all items from index \(i\) to index \(j\) of the list with step \(k\).

This implementation is quite complex compared to the rest and this complexity was the major inspiration for this article because while I was studying it, it took me some time to understand how it worked.

So I will advise that you read this section carefully and if you need to read it more than once it is totally fine. All that matters is that you understand it.

We continue with our illustration list \(s\)

To slice \(s\) from index \(i\) to index \(j\) with step \(k\) we use \(s[i:j:k]\)

Where \(i\) and \(j\) still maintain their definition from the last section

And \(k\) is either a positive or negative integer known as step

This slice operation is defined as the sequence of items with index \(x = i + n*k\) such that \(0

I know this sounds like a whole lot but I promise you it is simple and I will show you.

First, let us be clear that while \(i\) and \(k\) are any integer values of our choice that are not greater than \(len(s)\)

The values of \(n\) starts from \(0\) and increases in arithmetic progression to any integer that is less than the solution of \((j-i)/k\)

sips water

So for instance if we say \(i=0\) , \(j=4\) and \(k=2\)

The slice of \(s\) from \(i\) to \(j\) with step \(k\) will be written as \(s[0:4:2]\)

But for us to know the index of items that will be sliced from the list,

We first need to know the solution of \((j-i)/k\) because it will determine the actual upper limit for the values of \(n\).

so using the values for \(i, j, k\) in the calculation, we see that

\((4-0)/2\)

equals \(2\)

And this means that the values of \(n\) cannot be greater than or equal to \(2\) when calculating for \(x\) which is the index of items that will be sliced.

Recall \(x = i + n*k\)

Therefore the items that will be sliced will be all items in the list that have an index equal to \(x\) when \(n\) is less than \(2\)

Such that the values of \(n\) in this case will only be \(0\) and \(1\) since these are the only positive whole numbers that are less than \(2\)

We can then calculate the values of \(x\) as follows:

For \(n = 0\) we have \(x = 0 + 0 * 2\) which is equal to \(0\)

and for \(n = 1\) we have \(x = 0+ 1 * 2\) which is equal to \(2\)

Let's see the code example:

Slice vowels list items from index \(0\),to index \(4\) and step \(2\),

# slice vowels list items from index 0 to index 4 with step 2 
vowels[0:4:2]

The output of this slice operation is letters 'a','i'.

And if you count the indexes of the items in the vowels list these letters are the items at index \(0\) and index \(2\)

There is more

if \(i\) or \(j\) is omitted or None, they become "end" values ( which end depends on the sign of \(k\)`)

And if \(k\) is None, it is treated like \(1\) because \(k\) cannot be zero.

And with that, we have come to the end of the article.

if you got some insights from it, please share and like it to encourage me to do more like it.

If you have any questions please drop a comment and I will respond as soon as I can.

Thank you so much for your time.