Table of Contents
- Introduction
- Basic List Operations
- List Indexing and Slicing
- Mutable vs Immutable Objects
- List Methods
Introduction
The list is one of the most important data structures available in Python used to store multiple items in a single variable. It is written as a sequence of comma-separated values enclosed within a pair of square brackets [
]
. Note that the items in a list need not be of the same type.
Example
Definiting a list.1listA = [1, 2, 3, 4, 5, 6]
2listB = ["a", "b", 'c', "d",'f']
3listC = ['UK', 'USA', True, 2021, 2022]
4print(listA, listB,listC)
5print(type(listA), type(listB), type(listC))
[1, 2, 3, 4, 5, 6] ['a', 'b', 'c', 'd', 'f'] ['UK', 'USA', True, 2021, 2022]
<class 'list'> <class 'list'> <class 'list'>
In the above example, the first 2 lists store homogeneous data (values have the same type) whereas the last one stores heterogeneous data (values of different types).
Basic List Operations
Just like strings, lists can also be concatenated with the +
operator.
Example
Concatenation of lists.1listA+listB
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 'f']
We can obtain the length of a list using the len()
function.
Example
Length of a list.1len(listA)
6
Example
Repetition using the*
operator.
1listB*2
['a', 'b', 'c', 'd', 'f', 'a', 'b', 'c', 'd', 'f']
The in
keyword serves two purposes:
- used to check if a value is present in a sequence (e.g. list).
- used to iterate through a sequence in a
for
loop.
Example
Boolean expression with a list.12022 in listC # Is 2022 an element of listC?
True
A nested list is a list that contains other lists as its elements.
Example
Nested list.1newlist = [listA, listB]
2newlist
[[1, 2, 3, 4, 5, 6], ['a', 'b', 'c', 'd', 'f']]
ADVERTISEMENT
List Indexing and Slicing
Indexing and slicing for lists are similar to those for strings .
Example
List indexing.1listA[0]
1
Example
Negative indexing (count from right).1listA[-2]
5
Example
List slicing.1listA[2:]
[3, 4, 5, 6]
Chain indexing and slicing work for a nested list.
Example
1newlist[0] # first sub-list of a nested list
[1, 2, 3, 4, 5, 6]
Example
1newlist[1][2:4]
['c', 'd']
Example
Matrix: a nested list.1row1 = [1,2,3]
2row2 = [4,5,6]
3row3 = [7,8,9]
4mat = [row1, row2, row3]
5mat
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
We can print out individual elements of a list by putting an asterisk * in front of the list in a print()
statement.
Example
Printing individual elements of a list.1print(*listA)
1 2 3 4 5 6
If we want to print out the elements of a list line by line, we can use the \n
(new line character) as the sep
argument.
Example
Printing individual elements of a list (line by line).1print(*listA, sep='\n' )
1
2
3
4
5
6
Combining what we have learnt above, we can print out a matrix, row by row, using:
Example
Printing a nested list in matrix form.1print(*mat, sep='\n')
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Example
Chain indexing of a nested list.1mat[0][1] # first row, second element
2
The above procedure can be used to define a matrix but we will be using the more specialized NumPy arrays for that purpose.
Mutable vs Immutable Objects
It is appropriate at this juncture to digress into a discussion on mutability and immutability of Python objects. All the data in Python is represented by objects (or by relations between objects). Every object has an identity, a type, and a value. So far, all the basic data types in Python we have studied are immutable. Integers (int
), floats (float
) and strings (str
) are all immutable.
For example, in the following, the object represented by variable a
contains data “Singapore” and has type str
. It has an identity which can be found using the function id()
which returns an integer representing its address in memory.
Example
Identity of an object usingid()
.
1a="Singapore"
2print(a)
3print(type(a))
4print(id(a))
Singapore
<class 'str'>
2269554790960
If we try to modify the object by appending “an”, the identity changes which means the variable a
no longer refers to the original object. In other words, the original object (with the original id above) hasn’t changed at all since strings are immutable. A new object (with a new id) is created when we append “an” to a
and is now referenced by the same variable a
. The variable a
no longer refers to the original object.
Example
Strings are immutable.1a = a + "an"
2print(a)
3print(id(a))
Singaporean
2269554498992
On the other hand, lists are mutable as demostrated in the following example.
Example
Identity of a list object.1myList = ['foo','bar','cup']
2print(myList)
3print(id(myList))
['foo', 'bar', 'cup']
2269554819584
We now modify the second element of the list.
Example
Lists are mutable.1myList[1] = 'hat'
2print(myList)
3print(id(myList))
['foo', 'hat', 'cup']
2269554819584
We realize the identity of the list object remains unchanged after the modification. We say that list has been modified in place. This shows that lists are mutable Python objects.
As a second example, we create a list object and refer to it using 2 different variable names.
Example
A list object with two variable names.1values = [1, 2, 3]
2values2 = values
3print(id(values))
4print(id(values2))
2269554820608
2269554820608
We now modify the second list object (values2
) by making an appendment. Since lists are mutable, the object is modified in place and its identity remains unchanged.
Example
Modifying a mutable object with two variable names.1values2.append(4)
2print(values)
3print(values2)
4print(id(values))
5print(id(values2))
[1, 2, 3, 4]
[1, 2, 3, 4]
2269554820608
2269554820608
Since we have used two variable names to refer to the same mutable object whose identity remains unchanged, it isn’t surprising to observe that the variable names continue to have the same identity.
If a list object is referred to by two variable names, when we change the value of one variable, the value of the other variable is also changed automatically. This happens only for mutable objects.
Let’s try to repeat the above exercise with an immutable string object.
Example
A string object with two variable names.1text = "Singapore"
2text2 = text
3print(text)
4print(text2)
5print(id(text))
6print(id(text2))
Singapore
Singapore
2269554830000
2269554830000
Both text
and text2
point to the same string object and therefore have the same identity. We now modify the string object by making an appendment. Since strings are immutable, a new object is created and its identity changes.
Example
Modifying an immutable object with two variable names.1text = text+ "an"
2print(text)
3print(text2)
4print(id(text))
5print(id(text2))
Singaporean
Singapore
2269554828336
2269554830000
When Python executes the first statement, a new object (with a new id) is created and is referenced by the same variable name text
which no longer refers to the original object. Therefore, the identity changes. That is, id(text
) is not the same as the previous id(text
). However, variable text2
still refers to the original object (which hasn’t been modified). Therefore, both value and identity of text2
are the same as the previous text2
.
ADVERTISEMENT
List Methods
Python has a set of built-in methods that we can use on lists. Let’s first create a list object.
1fruits = ["apple", "banana", "orange"]
2fruits
['apple', 'banana', 'orange']
The append()
method appends an element to the end of the list.
Example
append()
method.
1fruits.append('pineapple')
2fruits
['apple', 'banana', 'orange', 'pineapple']
Note that the method append()
has modified the original object (identity remains unchanged).
The sort()
method sorts the list alphabetically in ascending order by default.
Example
sort()
: ascending order.
1cats =["Jaguar", "Lion", "Puma", "Leopard", "Panther", "Cheetah", "Tiger" ]
2cats.sort()
3cats
['Cheetah', 'Jaguar', 'Leopard', 'Lion', 'Panther', 'Puma', 'Tiger']
To sort the list alphabetically in descending order, we set the “reverse” parameter as True.
Example
sort()
: descending order.
1cats.sort(reverse=True)
2cats
['Tiger', 'Puma', 'Panther', 'Lion', 'Leopard', 'Jaguar', 'Cheetah']
By default, the sort()
method sorts the list in ascending order.
Example
sort()
: ascending order.
1numbers =[8,2,7,3,5,12,3]
2numbers.sort()
3numbers
[2, 3, 3, 5, 7, 8, 12]
Or sorting the numbers in descending order.
Example
sort()
: descending order.
1numbers.sort(reverse=True)
2numbers
[12, 8, 7, 5, 3, 3, 2]
The extend()
method extends an existing list by appending more elements. This is in contrast to the append()
method that appends only one element at a time.
Example
extend()
method.
1students =["Jane", "Tom", "Bruce"]
2more_students = ["Janet", "Wendy", "James"]
3students.extend(more_students)
4students
['Jane', 'Tom', 'Bruce', 'Janet', 'Wendy', 'James']
Or recall that we can simply concatenate the 2 lists with the +
operator
Example
Concatenation with+
.
1students =["Jane", "Tom", "Bruce"]
2students + more_students
['Jane', 'Tom', 'Bruce', 'Janet', 'Wendy', 'James']
The insert()
method inserts an element at a specified index location.
Example
insert()
method.
1fruits = ['apple', 'banana', 'orange', 'pineapple']
2fruits.insert(2,'pear') # inserts at index=2
3fruits
['apple', 'banana', 'pear', 'orange', 'pineapple']
The pop()
method removes an element at a specified index location.
Example
pop()
method.
1fruits.pop(3) # removes element at index=3
2fruits
['apple', 'banana', 'pear', 'pineapple']
The count()
method returns the number of elements with the specified value.
Example
count()
method.
1numbers = [1,2,2,2,3,3,4,5,6,6,8]
2numbers.count(3) # counts how many times the number 3 appears
2
The index()
method searches the list for a specified value and returns its index.
Example
index()
method.
1numbers.index(5)
7
In cases where there is more than one occurrence of the specified value, the index() method will only return the first index.
Example
index()
method returns only the index of the first occurrence.
1numbers.index(2)
1
What if we want to have the indices of all occurrences of the specified value? We will discuss this case when we learn about control flow and list comprehension in a later section.
The copy()
method returns an exact copy of the list.
Example
copy()
method.
1a=[1,2,3]
2b=a.copy()
3b
[1, 2, 3]
But why not just use
b=a
to duplicatea
?
Answer: recall that lists are mutable. There are consequences in using the expression b=a
. This means that whatever happens to a
will happen to b
since they refer to the same list object. If you only want to create an independent duplicate of a
, the copy()
method is more appropriate. The following example further illustrates this point.
ADVERTISEMENT
Example
copy()
method and mutability of a list object.
Scenario 1: b
is created from b=a.copy()
.
Whatever happens to a
will not affect b
.
1a=[1,2,3]
2b=a.copy()
3a[0] = 10
4b
[1, 2, 3]
Scenario 2: b
is created from b=a
.
Whatever happens to a
will impact b
.
1a=[1,2,3]
2b=a
3a[0] = 10
4b
[10, 2, 3]
The following table summarizes the Python list methods we have discussed so far:
Method | Description |
---|---|
append() |
Adds an element at the end of the list. |
copy() |
Returns a copy of the list. |
count() |
Returns the number of elements with the specified value. |
clear() |
Removes all the elements from the list. |
extend() |
Add the elements of a list to the end of the current list. |
index() |
Returns the index of the first element with the specified value. |
insert() |
Adds an element at the specified position. |
pop() |
Removes the element at the specified position. |
remove() |
Removes the first item with the specified value. |
reverse() |
Reverses the order of the list. |
sort() |
Sorts the list. |