Summary: Slicing is a Python concept to extract a subsequence from a string or list—that lies within a start
and stop
index range. There are two syntactical ways to define a slice. (1) The extended slice notation makes use of a colon : in string_name[start:stop:step]
. (2) The slice()
constructor defines the index range in string_name[slice(start:stop:step)]
.
Here are some basic examples:
Exercise: Create two more examples in the interactive code shell.
Let’s learn about the slicing notation in a step-by-step manner.
Fundamentals Of Indexing
Before we dive into our discussion on slice notation in Python, let us have a quick look at what are indexes and how indexing works.
An index can be considered as the position of an element in an ordered data type (like a file or tuple). A string can be considered as a list of characters with each character having an index.
- Indexing starts from zero to the length-1.
- Python also supports negative indexing.
Let’s visualize indexing with the help of a diagram:
Now that we have an idea about indexes, let us dive into our topic, i.e., the slice notation.
Introduction To Slicing
Definition:
Slicing refers to a concept in Python that allows us to extract a part of a string or a list or any other sequence based on a given start and stop index.
Syntax:
- Slicing uses
[]
with start, stop and step arguments separated by:
notation. - start determines the index from which slicing/extraction of elements of the string/sequence begins.
- If the start index is not specified, it is considered 0.
- stop determines the last index until which slicing is performed, however, the stop/last index is excluded while generating the substring. This means that the last index that is taken into consideration while generating the output (substring) is
stop-1
. This is a very important point to remember to avoid unexpected outputs and bugs in code. - If the stop index is not specified, it is considered the length of the entire string or the given sequence.
- step determines the increment between each index while slicing the sequence.
- It is an optional argument. As a matter of fact, all three arguments are optional. We will soon discover how!
- If the
step
is not specified it is considered to have a default value of 1, i.e. an increment of 1 between the indexes.
Example:
Please follow the example given below to have a look at the concepts discussed above. (Please ensure that you read the comments along with the code to have a better grip on the concepts.)
name = "FINXTER" # [start:stop] --> items from start through stop-1 print(name[1:6]) # [:stop] --> items from the beginning of string through stop-1 print(name[:6]) # [start:] --> items from start through end of string print(name[1:]) # [start:stop:step] --> items from start through stop with step-size print(name[1:6:2]) # Entire String! print(name[:])
Output:
INXTE FINXTE INXTER IXE FINXTER
Step Size In Slicing
Though the step size is optional while slicing yet it has several applications and advantages. Therefore let us discuss some of the use cases that justify the importance of step size while slicing a sequence.
Use Case 1: Custom Increment Between Indexes While Slicing
As mentioned earlier if the step size is not specified then the increment between the indexes within the specified range is considered to be 1. This means that all the indexes within the specified range/slice of a given string will be taken into account and the entire substring will be generated as output without skipping any element in between. However, if we want to generate a string such that the value in between the indexes is incremented by any value other than 1 then we can use the step-size to specify such increments. In other words, the step size can be used to skip indexes within the specified slice.
Let us consider an example to understand how we can define a step-size and generate the desired output.
Example: Given the string “FPIYNTXHTOENR”; how to extract the elements at the even positions / odd indexes (considering the first position as 1)?
name = "FPIYNTXHTOENR" print(name[1:12:2])
Output:
PYTHON
Though the above program is self-explanatory; let us have a look at the following diagram to visualize the above snippet so that the concept of step-size is crystal clear.
Use Case 2: Negative Step Size
Slicing provides us with the facility of negative step size. Therefore you can slice through a sequence or a string in the reverse direction using the negative step size. This can be instrumental in operations like reversing a string.
Example: Given the string “MADAM”; check if the string is a palindrome using a negative step size.
# String which reads the same backward as forward is a Palindrome string name = "MADAM" # Reversing the string using a negative step-size palindrome = (name[::-1]) if name == palindrome: print(palindrome," is a Palindrome String. ")
Output:
MADAM is a Palindrome String.
Slicing Through Negative Indices
Just like the negative step size, slicing also provides us with the added advantage of extracting substrings using the negative index of the individual characters in the string. Let us have a look at the following example to understand how slicing works with negative indices:
Example:
Let us use negative indices to slice the above string. Please follow the code along with the comments given below:-
string = "HELLO WORLD" # [-start:-stop] print(string[-11:-6]) # [:stop] print(string[:-6]) # [start:] print(string[-5:]) # Entire String using negative Indexing print(string[-11:]) # [start:stop:step] print(string[-11:-6:2]) # -Index and -Step to slice and reverse string print(string[-1:-6:-1])
Output:
HELLO HELLO WORLD HELLO WORLD HLO DLROW
Using The slice() Constructor
In the above examples, we have actually used a slice()
object using a : notation within square brackets []. The slice()
is an inbuilt constructor that is used to create a slice object which represent a subset of an entire sequence.
The Syntax for using the slice object is:
- Both syntaxes are supported in Python while using the
slice()
object. - To substitute an argument with an empty entry, you can use
None
. For example to replicatestring[1:]
you can usestring[slice(1, None)]
Since we already have an idea about indexing and slicing, let us contrast and compare the slice()
object and the basic : based slice notation in Python.
string_name[slice(start, stop, step)]
is equivalent tostring_name[start:stop:step]
wherestart, stop and step
arguments have a similar meaning in both cases. Howeverslice()
objects have a slightly different behaviour based on the number of arguments.
The best way of comparing the two notations is to visualize them with the help of examples. Thus, let us dive into the code given below to compare and contrast slicing using the slice()
and Basic :
notation –
name = "FINXTER" print("Original String = ", name) print("\nScenario 1") # [start:stop] --> items from start through stop-1 print("Output Using : Notation >> ",name[1:6]) print("Output Using slice Object >> ",name[slice(1,6)]) print("\nScenario 2") # [:stop] --> items from beginning of string through stop-1 print("Output Using : Notation >> ",name[:6]) print("Output Using slice Object >> ",name[slice(6)]) print("\nScenario 3") # [start:] --> items from start through end of string print("Output Using : Notation >> ",name[1:]) print("Output Using slice Object >> ",name[slice(1,7)]) print("\nScenario 4") # [start:stop:step] --> items from start through stop with step-size print("Output Using : Notation >> ",name[1:6:2]) print("Output Using slice Object >> ",name[slice(1,6,2)]) print("\nScenario 5") # Entire String! print("Output Using : Notation >> ",name[:]) print("Output Using slice Object >> ",name[slice(7)])
Output:
Original String = FINXTER Scenario 1 Output Using : Notation >> INXTE Output Using slice Object >> INXTE Scenario 2 Output Using : Notation >> FINXTE Output Using slice Object >> FINXTE Scenario 3 Output Using : Notation >> INXTER Output Using slice Object >> INXTER Scenario 4 Output Using : Notation >> IXE Output Using slice Object >> IXE Scenario 5 Output Using : Notation >> FINXTER Output Using slice Object >> FINXTER
Forgiving Syntax Of Slicing
Python is really forgiving when it comes to slicing because even if you specify an index that exceeds the actual maximum index of the sequence, you will not get an error and the output will be displayed on the screen without any hassle. Even if you start at an index that is not valid you won’t find an error, instead, python will simply return an empty string.
Let us have a look at the example given below which clarifies the forgiving syntax of slicing in Python:
name = "FINXTER" # prints entire string print(name[0:10000]) # prints empty string print(name[10000:10000]) # prints the element at first index print(name[0::10000]) # Using None is same as using a zero at beginning # or Not specifying any arguement print(name[None:]) print(name[2:None])
Output:
FINXTER F FINXTER NXTER
Slicing With Other Sequence Types
Until now we discussed slicing with respect to strings in all our examples. However, slicing works with every sequential data-type that can be indexed like a list or tuple. Let us have a look at the following program, which demonstrates slicing with respect to a list and a tuple.
Example:
li = ["apple","banana","Orange"] tup = ("Python","Java","C++") #slicing the list print(li[slice(0,2,1)]) print(li[slice(1)]) print(li[slice(None)]) # slicing the tuple print(tup[0:2:1]) print(tup[:1]) print(tup[::])
Output:
['apple', 'banana'] ['apple'] ['apple', 'banana', 'Orange'] ('Python', 'Java') ('Python',) ('Python', 'Java', 'C++')
Conclusion
The key takeaways from this article are :
- Fundamentals of Indexing.
- Slicing using the
[start:stop:step]
notation. - Slicing using the
slice()
object. - Step Size and its use cases.
- Slicing using the negative Indices.
- Slicing of other sequential data types.
We have a similar blog article where Christian Mayer has discussed some of the most frequently asked questions on slicing. Please have a look at the article by following this link. I hope you found this article on slicing notation useful. Please subscribe and stay tuned for more interesting articles!
Where to Go From Here?
Enough theory. Let’s get some practice!
Coders get paid six figures and more because they can solve problems more effectively using machine intelligence and automation.
To become more successful in coding, solve more real problems for real people. That’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?
You build high-value coding skills by working on practical coding projects!
Do you want to stop learning with toy projects and focus on practical code projects that earn you money and solve real problems for people?
🚀 If your answer is YES!, consider becoming a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.
If you just want to learn about the freelancing opportunity, feel free to watch my free webinar “How to Build Your High-Income Skill Python” and learn how I grew my coding business online and how you can, too—from the comfort of your own home.