Introduction to Python - Lesson 3
Lesson 3 - Complex Data Structures in Python: Lists
3.1 - Complex Data Structures - Lists
- Complex Data Structures in Python are: Lists, Tuples, Sets, Dictionaries.
- To these we should add strings, because they are sequences of characters, but we prefere to categorize them as basic data structures.
- Generally, we understand as a Complex Data Structure a type of data that contains more different type of data.
- They can be sequential or contain sequential data.
Lists
- Lists are mutable and ordered collections of items.
- Lists are used to store multiple items in a single variable.
- The items in a list do not need to be of the same data type.
- it is an ordered collection or sequence of items. Therefore, we can access items by referring to their position in the list.
- We can use indexing to access items in a list.
- We put elements inside square brackets:
[ el1, el2, el3 ]
1
2
3
4
5
6
7
8
# list with the same type of elements
shopping_list = ['bread', 'milk', 'oil', 'eggs']
math_marks = [78, 89, 90, 100]
hiking_coordinates = [(40.7128, -74.0060), (34.0522, -118.2437)]
voting_for_president_Tom = [True, False, True, True, False]
# lists with different types of elements
mixed_list = ['a', 10, 10.5, True]
3.2 Accessing the items in a list
- we use the index number and square bracket notation to access the items in a list
- the index number starts from 0
Syntax:
list_name[index_number]
1
2
3
4
5
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(shopping_list[0])
print(shopping_list[1])
print(shopping_list[2])
print(shopping_list[3])
1
2
3
4
bread
milk
oil
eggs
1
2
3
4
5
6
7
# negative index
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(shopping_list[-1])
print(shopping_list[-2])
print(shopping_list[-3])
print(shopping_list[-4])
1
2
3
4
eggs
oil
milk
bread
- if we use an index number that is out of the range of the list, we will get an error message
1
2
3
4
# out of range error
friends_list = ['Tom', 'Jerry', 'Spike']
print(friends_list[3])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[3], line 4
1 # out of range error
2 friends_list = ['Tom', 'Jerry', 'Spike']
----> 4 print(friends_list[3])
IndexError: list index out of range
- we can also use slicing to get the part of the list
- slicing can be also used to reverse the list
1
2
3
4
# slicing
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(shopping_list[0:2])
1
['bread', 'milk']
- we can also use negative indexes
1
2
3
4
# reverse slicing - reversing of the list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(shopping_list[::-1])
1
['eggs', 'oil', 'milk', 'bread']
3.3 Changing the value of an item
- we can change the value of an item in a list
- we use the index number to change the value of an item
1
2
3
4
5
6
# change values
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(shopping_list)
shopping_list[0] = 'butter'
print(shopping_list)
1
2
['bread', 'milk', 'oil', 'eggs']
['butter', 'milk', 'oil', 'eggs']
3.4 len() function
- we can use the len() function to get the length of the list
- it returns the number of items in the list
- syntax:
len(list_name)
1
2
3
4
5
6
# length of a list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print(len(shopping_list))
1
4
3.5 Removing items from a list
clear()
function removes all the items from the list- syntax:
list_name.clear()
- syntax:
pop()
function removes the last item from the list and returns it- syntax:
list_name.pop()
- we can also remove an item by specifying the index number and recieve the removed item
- syntax:
list_name.pop(index_number)
- syntax:
remove(value)
function removes the item with specified value from the list- syntax:
list_name.remove(value)
- syntax:
del
function removes the item at the specified index, or a slice from the list- syntax:
del list_name[index_number]
- removes item - syntax:
del list_name[start_index:end_index]
- removes items from start_index to end_index
- syntax:
1
2
3
4
5
# clear
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.clear()
print(shopping_list)
1
[]
1
2
3
4
5
# pop
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.pop()
print(shopping_list)
1
['bread', 'milk', 'oil']
1
2
3
4
5
6
7
8
9
10
11
# remove
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.remove('oil')
print(shopping_list)
# example 2 - only first occurrence will be removed
test_marks = [78, 89, 90, 100, 89, 67, 89]
test_marks.remove(89)
print(test_marks)
1
2
['bread', 'milk', 'eggs']
[78, 90, 100, 89, 67, 89]
1
2
3
4
5
6
7
8
9
10
11
# del
shopping_list = ['bread', 'milk', 'oil', 'eggs']
del shopping_list[0]
print(shopping_list)
# example 2
test_marks = [78, 89, 90, 100, 89, 67, 89]
del test_marks[1:3]
print(test_marks)
1
2
['milk', 'oil', 'eggs']
[78, 100, 89, 67, 89]
3.6 Adding elements to a list
append()
function adds an item to the end of the list- syntax:
list_name.append(value)
- syntax:
insert()
function adds an item at the specified index- syntax:
list_name.insert(index_number, value)
- syntax:
1
2
3
4
5
# append item to a list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.append('chocolate')
print(shopping_list)
1
['bread', 'milk', 'oil', 'eggs', 'chocolate']
1
2
3
4
5
# insert item to a list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.insert(0, 'chocolate') # inserts 'chocolate' at index 0, and moves the rest of the items to the right
print(shopping_list)
1
['chocolate', 'bread', 'milk', 'oil', 'eggs']
3.7 Checking if an item is in a list
in
keyword - if the value is in the list- syntax:
value in list
- syntax:
not in
keyword - if the value is not in the list- syntax:
value not in list
- syntax:
1
2
3
4
5
6
7
8
9
10
11
12
# check value in the list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
if 'oil' in shopping_list:
print('yes, the oil is in the list')
else:
print(shopping_list)
print('oh, no! you have forgotten to buy oil')
# shopping_list.append('oil')
# print(shopping_list)
# print('we have added oil to your list. now it is all fine!')
# print(shopping_list)
1
yes, the oil is in the list
3.8 Sorting a list
sort()
function sorts the list- syntax:
list_name.sort()
- syntax:
reverse()
function reverses the list- syntax:
list_name.reverse()
- syntax:
- these functions do not return any value, but they change the original list
1
2
3
4
5
6
7
8
9
# sort
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.sort()
print(shopping_list)
# reverse with sort
shopping_list.sort(reverse=True)
print(shopping_list)
1
2
['bread', 'eggs', 'milk', 'oil']
['oil', 'milk', 'eggs', 'bread']
1
2
3
4
5
# reverse()
shopping_list = ['bread', 'milk', 'oil', 'eggs']
shopping_list.reverse()
print(shopping_list)
1
['eggs', 'oil', 'milk', 'bread']
- if we want to sort the list, but don’t want to change the original list we can use sorted() function
- syntax:
sorted(list_name)
- syntax:
- if we want to reverse the list, we can use
sorted(list_name, reverse=True)
1
2
3
4
5
6
7
8
9
10
11
12
# sorted
shopping_list = ['bread', 'milk', 'oil', 'eggs']
print("sorted list:", sorted(shopping_list))
print("original list:", shopping_list)
# reverse with sorted
print("reverse sorted list:", sorted(shopping_list, reverse=True))
print("original list:", shopping_list)
1
2
3
4
sorted list: ['bread', 'eggs', 'milk', 'oil']
original list: ['bread', 'milk', 'oil', 'eggs']
reverse sorted list: ['oil', 'milk', 'eggs', 'bread']
original list: ['bread', 'milk', 'oil', 'eggs']
3.9 Finding the index of an item
index()
function returns the index of the first occurrence of the specified value- syntax:
list_name.index(value)
- syntax:
count()
function returns the number of times the specified value appears in the list- syntax:
list_name.count(value)
- syntax:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# find the index of an item
shopping_list = ['bread', 'milk', 'oil', 'eggs']
# print(shopping_list.index('oil'))
# print(shopping_list.index('milk'))
# print(shopping_list.index('bread'))
# print(shopping_list.index('eggs'))
# find and index of a repeating item
test_marks = [78, 89, 90, 100, 89, 67, 89]
print(test_marks.index(89))
# if we want to find a second occurence, we need to start from the index that comes after the first occurence
print(test_marks.index(89, 2))
# if we want to find the last occurence
print(test_marks.index(89, -2))
1
2
3
1
4
6
3.10 Looping/iterating through a list
- we can loop/iterate through a list by using a for loop in different ways:
- looping through the indices of the list:
1 2
for index in range(len(my_list)): print(my_list[index])
- looping through the list items:
1 2
for item in my_list: print(item)
- looping through the list items and indices - we use a function called
enumerate()
. It gives us the index and the value:1 2
for index, item in enumerate(my_list): print(index, item)
- looping through the indices of the list:
1
2
3
4
5
6
# looping through indices of a list
shopping_list = ['bread', 'milk', 'oil', 'eggs']
for i in range(len(shopping_list)):
print(i, shopping_list[i])
1
2
3
4
0 bread
1 milk
2 oil
3 eggs
1
2
3
4
5
6
# looping through a list items
shopping_list = ['bread', 'milk', 'oil', 'eggs']
for item in shopping_list:
print(item)
1
2
3
4
bread
milk
oil
eggs
1
2
3
4
5
6
# looping through a list items and indices
shopping_list = ['bread', 'milk', 'oil', 'eggs']
for i, item in enumerate(shopping_list):
print(i, item)
1
2
3
4
0 bread
1 milk
2 oil
3 eggs
- we can also loop through a list with a while loop
1 2 3 4 5
index = 0 while index < len(my_list): print(my_list[index]) index += 1
3.10.a Paralel loops
Sometimes we need to loop through two or more lists in parallel.
- we can use the
zip()
function to loop through lists in parallel- syntax:
zip(list1, list2)
- if the lists have different lengths, the longer list will be truncated
- syntax:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# loop through two lists together
shopping_list = ['bread', 'milk', 'oil', 'eggs']
test_marks = [78, 89, 90, 100, 89, 67, 89]
for item, mark in zip(shopping_list, test_marks):
print(item, mark)
print()
# loop through three lists of different lengths
shopping_list = ['bread', 'milk', 'oil', 'eggs']
test_marks = [78, 89, 90, 100, 89, 67, 89, 89]
validation_marks = [True, True, True, True, False, True, True, False]
for item, mark, valid in zip(shopping_list, test_marks, validation_marks):
print(item, mark, valid)
1
2
3
4
5
6
7
8
9
bread 78
milk 89
oil 90
eggs 100
bread 78 True
milk 89 True
oil 90 True
eggs 100 True
3.11 Copying a list
- there’s one issue with the lists. Let us consider the following code:
1
2
3
4
5
6
a = 3
b = a
print(f"a={a}, b={b}")
a = 5
print(f"a={a}, b={b}")
1
2
a=3, b=3
a=5, b=3
If we do the same with a list, it will not work the same:
1
2
3
4
5
6
list_a = [1, 2, 3]
list_b = list_a
print(f"list_a={list_a}, list_b={list_b}")
list_a[0] = 5
print(f"list_a={list_a}, list_b={list_b}")
1
2
list_a=[1, 2, 3], list_b=[1, 2, 3]
list_a=[5, 2, 3], list_b=[5, 2, 3]
What happened here? The problem is that the list list_b
is a reference to the list list_a
. Therefore, if we change the value of list_a[0]
then the value of list_b
will also change. If we wish to take the same list and then change the value of the new variable that contains the list, without changing the original list, we can use the copy()
function:
- syntax:
list_name.copy()
1
2
3
4
5
6
7
8
# copy of a list
list_a = [1, 2, 3]
list_b = list_a.copy()
print(f"list_a={list_a}, list_b={list_b}")
list_a[0] = 5
print(f"list_a={list_a}, list_b={list_b}")
1
2
list_a=[1, 2, 3], list_b=[1, 2, 3]
list_a=[5, 2, 3], list_b=[1, 2, 3]
- We can also make a copy of a list with the
list()
function: - syntax:
list(list_name)
1
2
3
4
5
6
7
8
# copy a list with list()
list_a = [1, 2, 3]
list_b = list(list_a)
print(f"list_a={list_a}, list_b={list_b}")
list_a[0] = 5
print(f"list_a={list_a}, list_b={list_b}")
1
2
list_a=[1, 2, 3], list_b=[1, 2, 3]
list_a=[5, 2, 3], list_b=[1, 2, 3]
- there’s another way to make a copy of a list. We can use list slicing operator
[:]
:- syntax:
list_name[:]
- syntax:
1
2
3
4
5
6
7
# copy list with [:]
list_a = [1, 2, 3]
list_b = list_a[:]
print(f"list_a={list_a}, list_b={list_b}")
list_a[0] = 5
print(f"list_a={list_a}, list_b={list_b}")
1
2
list_a=[1, 2, 3], list_b=[1, 2, 3]
list_a=[5, 2, 3], list_b=[1, 2, 3]
3.12 Converting list to string
- we can convert a list to a string with the
.join()
function:- syntax:
"x".join(list_name)
- wherex
is a joing string/character, but only if all elements in the list are strings.
- syntax:
1
2
3
4
5
6
# convert list to a string with join()
list_a = ['1', '2', '3']
list_b = '*'.join(list_a)
print(list_b)
1
1*2*3
3.13 Converting string to list
- we can convert a string to a list with the
.split()
function:- syntax:
list_name.split("x")
- wherex
is a split string/character. If it is not specified, the default value is any white space.
- syntax:
- we can also specify the number of splits
- syntax:
list_name.split("x", number_of_splits)
- syntax:
1
2
3
4
5
6
7
8
9
10
11
12
# split string with split()
list_a = '1*2*3'
list_b = list_a.split('*')
print(list_b)
print(type(list_b))
# split a sentence
sentence = 'I am learning Python'
list_c = sentence.split()
print(list_c)
print(type(list_c))
1
2
3
4
['1', '2', '3']
<class 'list'>
['I', 'am', 'learning', 'Python']
<class 'list'>
3.14 Merging two lists
- we can merge/concatenate two lists with the
+
operator:- syntax:
list_a + list_b
- syntax:
1
2
3
4
5
6
7
8
# concatenation of two lists
list_a = [1, 2, 3]
list_b = [4, 5, 6]
list_c = list_a + list_b
print(list_c)
print(type(list_c))
1
2
[1, 2, 3, 4, 5, 6]
<class 'list'>
- we can also use the
extend()
function:- syntax:
list_name.extend(list_name)
- syntax:
1
2
3
4
5
6
7
8
# merging two lists with extend()
list_a = [1, 2, 3]
list_b = [4, 5, 6]
list_a.extend(list_b)
print(list_a)
print(type(list_a))
1
2
[1, 2, 3, 4, 5, 6]
<class 'list'>
3.15 Nested Lists
- we can create a nested list with the
[]
brackets:- syntax:
[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
- syntax:
- to access elements in a nested list we use the
[]
brackets and the indices - first index is for the outer list, second index is for the inner list
1
2
3
4
5
# nested list
my_nested_list = [1, 2, 3, [4, 5, 6], 7, 8, 9]
print(my_nested_list) # prints the outer list
print(my_nested_list[3]) # prints the list on index 3 of the outer list
print(my_nested_list[3][0]) # prints element on index 0 of the list on index 3 of the outer list
1
2
3
[1, 2, 3, [4, 5, 6], 7, 8, 9]
[4, 5, 6]
4
This post is licensed under CC BY 4.0 by the author.