Introduction
You are using list, tuple, string, and range types every day. Have you noticed all these types support common operations such as indexing, slicing, concatenation, repetition, and common functions such as min, max, len, count, and index? Is that a coincidence?
Well, no. It’s because list, tuple, string, and range belong to sequence type and hence they exhibit some common properties.
Operations that are common to Python sequence types:-
- Membership Operators (in and not in operator)
- Indexing & Slicing ( s[i:j:k])
- Concatenation (+)
- Repetition (*)
Functions that are common to Python sequence types:-
- min()
- max()
- len()
- count()
- index()
Python has many built-in types such as numeric types, sequence types (lists, tuples, range), text sequence types (string), set types (sets, frozen sets), mapping types (dictionaries), etc. The goal of this article is to give you an introduction to sequence types in Python.
Sequence Types
As the name itself says, sequence type consists of a sequence of elements. They are also called ordered set because the order in which the elements are inserted is maintained and can be accessed based on their index position. Below is an example of the string sequence type.
As per Python documentation, list, tuple, and range are considered as the basic sequence types. String type comes under text sequence type and bytes & byte arrays are binary sequence types. In this article, we only look into basic sequence types and text sequence types. Binary sequence types will be converted in a future article.
We can also classify all the three sequence types into the below 2 categories:
- Mutable: list, byte arrays
- Immutable: tuple, range, strings, bytes
If you need to refresh your memory about mutability and immutability in Python, I invite you to go through this article.
Let’s now understand the common sequence operations and the functions. Most of these operations and functions are supported by mutable and immutable objects.
Common Sequence Type Operations
Membership operators
The in and not in are the membership operators. The in operator returns True if the element is found in the sequence else False. On the other hand, as expected, not in operator works the opposite.
>>> 30 in [30, 20, 10, 40, 50]
True
>>> 10 not in [30, 20, 10, 40, 50]
False
With string, bytes, and byte arrays sequences, membership operators work differently by checking subsequence in the given sequence.
>>> "Sim" in "Python Simplified"
True
Slicing
The slicing operation is used to access a subset of the given sequence without affecting the original content. For example, in a list with 5 elements my_list = [1,2,3,4,5], if you want to access elements 3 & 4, then you can use slicing as my_list[2:4].
seq[i: j: k]
where,
i = start index position
j = end index position
k = step size from start to end
Let’s consider below list and string example to show how slicing works. Please refer to the image below when going through the indexing and slicing examples for better understanding.
>>> my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> my_string = "Python Simplified"
Indexing – Indexing returns the element at the given index position of the sequence. Note that indexing starts from 0 (zero). So, 1st element is at index position 0, 2nd element is at index position 1, and so on.
>>> my_list[2]
3
>>> my_list[-2]
90
>>> my_string[2]
't'
Slicing without step – Below example uses start and stop index position. Note that the stop index position is not included in the slicing operation.
>>> my_list[3:6]
[4,5,6]
>>> my_list[-3:-1]
[8,9]
>>> my_string[3:6]
'hon'
Slicing with step – The below example uses the start position, end position, and step size. Both the examples below output the elements [1,3,5,7,9]. As you can see one example uses slicing without negative and another with negative indexing. Note that the stop index position is not included in the slicing operation.
>>> my_list[0:10:2]
[1, 3, 5, 7, 9]
>>> my_list[-10:-1:2]
[1, 3, 5, 7, 9]
Concatenation (+)
The concatenation operator joins all elements in given sequences and returns one sequence object. You can’t concatenate different types such as lists with tuples or strings with lists etc. The concatenating sequence types must be homogeneous else you will run to TypeError.
>>> list_1 = [10, 20]
>>> list_2 = [30, 40]
>>> tuple_1 = (1, 2)
>>> list_1 + list_1
[10, 20, 30, 40]
>>> list_1 + tuple_1
Traceback (most recent call last):
File "", line 1, in
TypeError: can only concatenate list (not "tuple") to list
Repetition (*)
The repetition operator returns the sequence s repeated n times.
>>> "python " * 5
'python python python python python '
>>> (1,2) * 3
(1, 2, 1, 2, 1, 2)
Common Sequence Type Functions
We will use the below list example to show the results of common sequence functions.
>>> my_list = [10, 20, 30, 40, 50]
>>> my_range = range(1,6)
>>> my_string = "abcde"
min()
Returns the smallest element in the given sequence s.
min(my_list)
>>> 10
min(my_range)
>>> 1
min(my_string)
>>> "a"
max()
Returns the largest elements in the given sequence s.
max(my_list)
>>> 50
max(my_range)
>>> 5
max(my_string)
>>> "e"
len()
Returns the length of the given sequence s.
len(my_list)
>>> 5
len(my_range)
>>> 5
len(my_string)
>>> 6
count()
Returns how many times an element x occurs in the given sequence. If an element is not found in the sequence it returns 0.
>>> my_list.count(10)
1
>>> my_list.count(1000)
0
>>> my_range.count(1)
1
>>> my_range.count(1000)
0
>>> my_string.count("a")
1
>>> my_string.count("z")
0
index()
Return the index of the first occurrence of an element x in the given sequence. If the element is not found in the sequence then it returns ValueError.
>>> my_list.index(10)
0
>>> my_range.index(2)
1
>>> my_string.index("c")
2
>>>my_list.index(1000)
Traceback (most recent call last):
File "", line 1, in
ValueError: 100 is not in list
Mutable Sequence Types
The sequence functions and operations that you just went through are common to all sequence types (irrespective of whether the object is mutable or immutable). Now, let’s go through the operations and functions that are supported by mutable sequence types (more specifically list type).
These operations and functions are only applicable to mutable sequence types because these result in changing the content of the sequence. That means you are mutating the sequence.
Operations
Here are the operations that are applicable to only mutable sequence types.
- Item assignment
- slice assignment
- item or slice deletion
item assignment: The individual element can be modified as shown in the below example.
>>> mylist = [1,2,3,4,5]
>>> mylist[0] = 10
>>> mylist
[10, 2, 3, 4, 5]
slice assignment: The group of elements within the sequence can be modified using slice assignment as shown below.
>>> mylist = [1,2,3,4,5]
>>> mylist[1:3] = 20, 30
>>> mylist
[1, 20, 30, 4, 5]
item or slice deletion: You can also delete one or more elements from the sequence using the del keyword.
>>> mylist = [1,2,3,4,5]
>>> del mylist[3:]
>>> mylist
[1, 2, 3]
Functions
These are the functions that are applicable to only mutable sequence types.
- append()
- clear()
- copy()
- extend()
- insert()
- pop()
- remove()
- reverse()
append(): It appends the element to the end of the given sequence.
>>> my_list = [1, 2, 3, 4]
>>> my_list.append(5)
>>> my_list
[1, 2, 3, 4, 5]
clear(): This clears the content of the sequence and returns an empty sequence.
>>> my_list = [1, 2, 3, 4, 5]
>>> my_list.clear()
>>> my_list
[]
copy(): Create a shallow copy of the given sequence.
>>> mylist_1 = [1,2,3,4,5]
>>> mylist_2 = mylist_1.copy()
>>> mylist_2
[1,2,3,4,5]
extend(): Extends the given sequence with contents passed to extend function. The argument to extend must be iterable which ultimately will be converted to a list and then its contents are appended to the given sequence.
>>> mylist = [1,2]
>>> mylist.extend([3,4])
>>> mylist.extend((5,6))
>>> mylist.extend({7,8})
>>> mylist.extend("Python")
>>> mylist
[1, 2, 3, 4, 5, 6, 7, 8, 'P', 'y', 't', 'h', 'o', 'n']
>>> mylist.extend(9)
Traceback (most recent call last):
File "", line 1, in
TypeError: 'int' object is not iterable
insert(): Inserts an element at a specified index position in a sequence.
>>> my_list = [1,2,4,5]
>>> my_list.insert(2,3)
>>> my_list
[1, 2, 3, 4, 5]
pop(): Removes and returns an element from the given index position. If the index is not specified, then by default, the last element is removed from the sequence.
>>> my_list = [1, 2, 3, 4, 5]
>>> my_list.pop(0)
1
my_list
>>> [2, 3, 4, 5]
remove(): Removes only the first occurrence of the element from the given sequence.
>>> my_list = [1,2,1,3,4,5]
>>> my_list.remove(1)
>>> my_list
[2, 1, 3, 4, 5]
reverse(): Reverses the elements in the sequence in place.
>>> my_list = [1,2,3,4,5]
>>> my_list.reverse()
>>> my_list
[5, 4, 3, 2, 1]
Immutable Sequence Types
The hash() is the only function that is implemented by immutable sequence types but not by mutable type. The hash function returns the hash value of the object passed to the hash function.
One of the use cases of hash values is when comparing dictionary keys. This is because comparing hash values is much faster than comparing the complete key values.
>>> hash(12345)
12345
>>> hash(123.45)
1037629354146168955
>>> hash('Python')
6716506239384282126
Conclusion
In this article, you have understood the Python sequence types, different types, operations, and functions supported by sequence types along with examples. The knowledge about sequence types is important as it paves the way for understanding more advanced concepts in Python. If you have any questions, please let us know in the comments section.