1. Using Lists

Quick Overview of Day

Creating lists. Checking the length of a list. Access elements of a list using the index operator. Using in and not in. Taking a slice of a list. Immutability of strings, mutability of lists. For loops with lists.

1.1. List Overview

We’ve been using lists throughout the course, so you probably already feel quite comfortable with them. Some of the following information will be a review for you, but we will spend a bit of time going into more depth than we have done up to now.

A list is a sequential collection of Python data values, where each value is identified by an index. The values that make up a list are called its elements. Lists are similar to strings, which are ordered collections of characters, except that the elements of a list can have any type and for any one list, the items can be of different types.

1.2. List Values

There are several ways to create a new list. The simplest is to enclose the elements in square brackets ( [ and ]).

[10, 20, 30, 40]
["spam", "bungee", "swallow"]

The first example is a list of four integers. The second is a list of three strings. As we said above, the elements of a list don’t have to be the same type. The following list contains a string, a float, an integer, and another list.

["hello", 2.0, 5, [10, 20]]

A list within another list is said to be nested and the inner list is often called a sublist. Finally, there is a special list that contains no elements. It is called the empty list and is denoted [].

As you would expect, we can also assign list values to variables and pass lists as parameters to functions.

1.3. List Length

As with strings, the function len returns the length of a list (the number of items in the list). However, since lists can have items which are themselves lists, it important to note that len only returns the top-most length. In other words, sublists are considered to be a single item when counting the length of the list.

1.3.1. Check Your Understanding

    lists-overview1: What is printed by the following statements?

    a_list = [3, 67, "cat", 3.14, False]
    print(len(a_list))
    
  • 4
  • len returns the actual number of items in the list, not the maximum index value.
  • 5
  • Yes, there are 5 items in this list.

    lists-overview2: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(len(a_list))
    
  • 7
  • Yes, there are 7 items in this list even though two of them happen to also be lists.
  • 8
  • len returns the number of top level items in the list. It does not count items in sublists.

1.4. Accessing Elements

The syntax for accessing the elements of a list is the same as the syntax for accessing the characters of a string. We use the index operator ( [] – not to be confused with an empty list). The expression inside the brackets specifies the index. Remember that the indices start at 0. Any integer expression can be used as an index and as with strings, negative index values will locate items from the right instead of from the left.

Also note that you can use the index operator [] more than once in a row to access things inside the list. For example, if you had a list of places in Saskatchewan, you could access both a place, as well as an individual character, as follows:

The same syntax works if you are trying to access an element of a list inside a list as well. Consider the following:

1.4.1. Check Your Understanding

    lists-overview3: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(a_list[5])
    
  • [ ]
  • The empty list is at index 4.
  • 3.14
  • Yes, 3.14 is at index 5 since we start counting at 0 and sublists count as one item.
  • False
  • False is at index 6.

    lists-overview4: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(a_list[2][0])
    
  • 56
  • Indexes start with 0, not 1.
  • c
  • Yes, the first character of the string at index 2 is c
  • cat
  • cat is the item at index 2 but then we index into it further.
  • Error, you cannot have two index values unless you are using slicing.
  • Using more than one index is fine. You read it from left to right.

1.5. List Membership

in and not in are boolean operators that test membership in a sequence. We used them previously with strings and they also work here.

1.5.1. Check Your Understanding

    lists-overview5: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(3.14 in a_list)
    
  • True
  • Yes, 3.14 is an item in the list a_list.
  • False
  • There are 7 items in the list, 3.14 is one of them.

    lists-overview6: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(57 in a_list)
    
  • True
  • in returns True for top level items only. 57 is in a sublist.
  • False
  • Yes, 57 is not a top level item in a_list. It is in a sublist.

1.6. List Slices

The slice operation we saw with strings also work on lists. Remember that the first index is the starting point for the slice and the second number is one index past the end of the slice (up to but not including that element). Recall also that if you omit the first index (before the colon), the slice starts at the beginning of the sequence. If you omit the second index, the slice goes to the end of the sequence.

1.6.1. Check Your Understanding

    lists-overview7: What is printed by the following statements?

    a_list = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(a_list[4:])
    
  • [ [ ], 3.14, False]
  • Yes, the slice starts at index 4 and goes up to and including the last item.
  • [ [ ], 3.14]
  • By leaving out the upper bound on the slice, we go up to and including the last item.
  • [ [56, 57, "dog"], [ ], 3.14, False]
  • Index values start at 0.

1.7. Strings are Immutable

One thing that makes strings different from Python lists is that you are not allowed to modify the individual characters in a string. It is tempting to use the [] operator on the left side of an assignment, with the intention of changing a character in a string. For example, in the following code, we would like to change the first letter of greeting.

Instead of producing the output Jello, world!, this code produces the runtime error TypeError: 'str' object does not support item assignment.

Strings are immutable, which means you cannot change an existing string. The best you can do is create a new string that is a variation on the original.

The solution here is to concatenate a new first letter onto a slice of greeting. This operation has no effect on the original string.

1.8. Lists are Mutable

Unlike strings, lists are mutable. This means we can change an item in a list by accessing it directly as part of the assignment statement. Using the indexing operator (square brackets) on the left side of an assignment, we can update one of the list items.

An assignment to an element of a list is called item assignment. Item assignment does not work for strings. Recall that strings are immutable.

1.8.1. Check Your Understanding

    lists-overview8: What is printed by the following statements?

    a_list = [4, 2, 8, 6, 5]
    a_list[2] = True
    print(a_list)
    
  • [4, 2, True, 8, 6, 5]
  • Item assignment does not insert the new item into the list.
  • [4, 2, True, 6, 5]
  • Yes, the value True is placed in the list at index 2. It replaces 8.
  • Error, it is illegal to assign
  • Item assignment is allowed with lists. Lists are mutable.

1.9. Lists and for loops

It is also possible to perform list traversal using iteration by item as well as iteration by index.

It almost reads like natural language: For (every) fruit in (the list of) fruits, print (the name of the) fruit.

We can also use the indices to access the items in an iterative fashion.

In this example, each time through the loop, the variable position is used as an index into the list, printing the position-eth element. Note that we used len as the upper bound on the range so that we can iterate correctly no matter how many items are in the list.

Since lists are mutable, it is often desirable to traverse a list, modifying each of its elements as you go. The following code squares all the numbers from 1 to 5 using iteration by position.

Take a moment to think about range(len(numbers)) until you understand how it works. We are interested here in both the value and its index within the list, so that we can assign a new value to it.

1.10. Practice Problems

1.10.1. Warmup

Create a list called my_list with the following six items: 76, 92.3, "hello", True, 4, 76. Print out the list to make sure it is doing what you intend.

1.10.2. Make it Fun

Note

The only thing you need to do for this question is to complete the function definition! You do not need to call the function, as that will be done automatically for you.

Write a function to replace the first element of a list with the word "fun", and then return the altered list. You can assume that the list will always have at least one element.

Examples:

make_fun(["computer", "science"]) ["fun", "science"]

make_fun(["sask", "is", "nice"]) ["fun", "is", "nice"]

make_fun(["we", "live", "in", "saskatchewan"]) ["fun", "live", "in", "saskatchewan"]

1.10.3. Sum of Squares

Note

The only thing you need to do for this question is to complete the function definition! You do not need to call the function, as that will be done automatically for you.

Write a function sum_of_squares(a_list) that computes the sum of the squares of the numbers in the list a_list. For example, sum_of_squares([2, 3, 4]) should return 29, which is the sum of 4+9+16.

Examples:

sum_of_squares([2,3,4]) 29

sum_of_squares([0,1,-1]) 2

sum_of_squares([5,12]) 169

1.10.4. Count Odd Numbers

Note

The only thing you need to do for this question is to complete the function definition! You do not need to call the function, as that will be done automatically for you.

Write a function to count how many odd numbers are in a list.

Examples:

count_odds([1,3,5,7,9]) 5

count_odds([1,2,3,4,5]) 3

count_odds([2,4,6,8,10]) 0

1.10.5. Count Words with Length 5

Note

The only thing you need to do for this question is to complete the function definition! You do not need to call the function, as that will be done automatically for you.

Write a function to count how many words in a list have a length of 5.

Examples:

count_words(["computer", "science"]) 0

count_words(["nobody", "knows"]) 1

count_words(["think", "pizza", "quick"]) 3

1.10.6. Look For “saskatchewan”

Note

The only thing you need to do for this question is to complete the function definition! You do not need to call the function, as that will be done automatically for you.

Write a function to check if the word “saskatchewan” shows up somewhere in a list. If it does, return True. If it doesn’t, return False.

Examples:

has_sask(["computer", "science"]) False

has_sask(["sask", "is", "nice"]) False

has_sask(["we", "live", "in", "saskatchewan"]) True

Next Section - 2. List Methods