12. Lists
Strings are collections of characters — we can generalize that idea
A
listis a collection that can hold any types, not just characters
Activity
Run the following code:
1some_list = [5, 7, 9, 10]
2print(some_list)
3print(some_list[0])
4print(some_list[1:3])
5print(type(some_list))
Determine what types can be in a list.
Can a list contain things of different types at the same time?
How can you access the last element in a list?
Can we find the length of a list?
Is it possible to have a list of length 0? This would be an empty list, or a list with nothing in it.
12.1. Data Structures
The
listis your first real data structureAs the name suggests, a data structure is some structure that holds data
Lists, although simple, are exceptionally useful and important
Activity
Apply what you know about loops, strings, and lists to solve the following problems — combining algorithms and data structures is a big part of programming. Hint: You will probably find the linear searches from the strings topic to be helpful.
Write a function
contains_while(needle, haystack) -> bool:that uses awhileloop and returnsTrueif needle is contained in the haystack andFalseotherwise.Write a function
index_of_for(needle, haystack) -> int:that uses aforloop and returns the index of needle within the haystack or-1if it is not found.Write some
asserttests for both functions to verify correctness.
12.2. List Operators and Methods
Similar to strings, we can concatenate lists with the
+operator1some_list = [5, 6, 7, 8, 9] 2some_other_list = ["this", "is", "a", "list"] 3bigger_list = some_list + some_other_list 4print(bigger_list) 5# Results in [5, 6, 7, 8, 9, 'this', 'is', 'a', 'list']
We can concatenate a list with itself multiple times using the
*operator1some_list = [5, 6, 7, 8, 9] 2triple_list = some_list * 3 3print(triple_list) 4# Results in [5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
Activity
Create some list and assign it to a variable
some_listprintout the list —print(some_list)After running the code, type
some_list.and waitDon’t forget the dot
.
Play around with some of the methods you see
12.3. Mutability
Although lists and strings have some things in common, one thing they do not have in common is mutability
Remember, strings are immutable
We can index strings and lists the same way to access individual elements
But unlike strings, we can also change the elements at a specific index
1another_list = ["a", "b", "c", "d", "e"]
2another_list[2] = "X"
3print(another_list)
4# Results in ['a', 'b', 'X', 'd', 'e']
12.4. Lists & Loops
Similar to how
forloops made it easy to iterate over each character in a stringforloops can be used the same way on lists to iterate over each element in the listforeach thing in a collection of things
1collection_of_things = ["Hello", 10, True, 100.001]
2
3for thing in collection_of_things:
4 print(thing)
5
6# Results in
7# Hello
8# 10
9# True
10# 100.001
Iterating over a collection of things is very common
Expect to start using
forloops like this a lot
12.4.1. Range
rangeis a very handy function that we often use withforloopsIt provides an easy way to loop over a specific range of numbers
1for i in range(5):
2 print(i)
3
4# Results in
5# 0
6# 1
7# 2
8# 3
9# 4
Notice that the integer
5was specified in therangefunction, and the loop ran a total of5timesBut because of
0based indexing, the number5is not actually included
The same can be done with a
whileloop, but the syntax is more cumbersome
1i = 0
2while i < 5:
3 print(i)
4 i += 1
5
6# Results in
7# 0
8# 1
9# 2
10# 3
11# 4
Activity
Write a function beer_on_wall that prints out "n bottles of beer on the wall" for all n from 99 down
to 0. This function must use a for loop with the range function.
12.4.2. Looping Over Indices and Enumerate
Sometimes it is important to know the indices of each element being printed out
For example, if the goal is to do a linear search to find the index of a given element, the following would be problematic
1def index_of_uhoh(needle, haystack):
2 for element in haystack:
3 if element == needle:
4 return "????" # How do I find the index?
5 return -1
Using the
rangefunction would help in this situation as we can use it to loop over each index inhaystackThe only catch is that we need to actually index
haystack
1def index_of(needle, haystack):
2 haystack_length = len(haystack)
3 for i in range(haystack_length):
4 if haystack[i] == needle:
5 return i
6 return -1
To make what is going on a little clearer, consider the following example
1another_list = ["a", "b", "c", "d", "e"]
2for i in range(len(another_list)):
3 print(i, another_list[i])
4
5# Results in
6# 0 a
7# 1 b
8# 2 c
9# 3 d
10# 4 e
This loop prints out the index (
i) along with the element at the given index (another_list[i])This functionality is quite common and Python even provides a shorthand for achieving it —
enumerate
1another_list = ["a", "b", "c", "d", "e"]
2for i, element in enumerate(another_list):
3 print(i, element)
4
5# Results in
6# 0 a
7# 1 b
8# 2 c
9# 3 d
10# 4 e
Here
elementalready holds the value at each index — no need to index the list manually