11.a. Lists - Part A

A list is an ordered collection of values. The values that make up a list are called its elements, or its items. We will use the term element or item to mean the same thing. Lists are similar to strings, which are ordered collections of characters, except that the elements of a list can be of any type. Lists and strings — and other collections that maintain the order of their items — are called sequences.

11.1. List values

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

ps = [10, 20, 30, 40]
qs = ["spam", "bungee", "swallow"]

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

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

A list within another list is said to be nested. More on this later in Lists - Part B.

Finally, a list with no elements is called an empty list, and is denoted [].

We have already seen that we can assign list values to variables or pass lists as parameters to functions:

11.2. Accessing elements

The syntax for accessing the elements of a list is the same as the syntax for accessing the characters of a string — 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:

>>> numbers[0]

Any expression evaluating to an integer can be used as an index:

>>> numbers[9-8]
>>> numbers[1.0]
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: list indices must be integers, not float

If you try to access or assign to an element that does not exist, you get a runtime error:

>>> numbers[2]
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
IndexError: list index out of range

It is common to use a loop variable as a list index.

Each time through the loop, the variable i is used as an index into the list, printing the i‘th element. This pattern of computation is called a list traversal.

The above sample doesn’t need or use the index i for anything besides getting the items from the list, so this more direct version — where the for loop gets the items — might be preferred:

11.3. List length

The function len returns the length of a list, which is equal to the number of its elements. If you are going to use an integer index to access the list, it is a good idea to use this value as the upper bound of a loop instead of a constant. That way, if the size of the list changes, you won’t have to go through the program changing all the loops; they will work correctly for any size list:

The last time the body of the loop is executed, i is len(horsemen) - 1, which is the index of the last element. (But the version without the index looks even better now!)

Although a list can contain another list, the nested list still counts as a single element in its parent list. The length of this list is 4:

>>> len(["car makers", 1, ["Ford", "Toyota", "BMW"], [1, 2, 3]])

11.4. List membership

in and not in are Boolean operators that test membership in a sequence. We used them previously with strings, but they also work with lists and other sequences:

Using this produces a more elegant version of the nested loop program we previously used to count the number of students doing Computer Science in the section Nested Loops for Nested Data:

11.5. List operations

The + operator concatenates lists:

Similarly, the * operator repeats a list a given number of times:

The first example repeats [0] four times. The second example repeats the list [1, 2, 3] three times.

11.6. List slices

The slice operations we saw previously with strings let us work with sublists:

11.7. Lists are mutable

Unlike strings, lists are mutable, which means we can change their elements. Using the index operator on the left side of an assignment, we can update one of the elements:

The bracket operator applied to a list can appear anywhere in an expression. When it appears on the left side of an assignment, it changes one of the elements in the list, so the first element of fruit has been changed from "banana" to "pear", and the last from "quince" to "orange". An assignment to an element of a list is called item assignment. Item assignment does not work for strings:

>>> my_string = "TEST"
>>> my_string[2] = "X"
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: 'str' object does not support item assignment

but it does for lists:

With the slice operator we can update a whole sublist at once:

We can also remove elements from a list by assigning an empty list to them:

And we can add elements to a list by squeezing them into an empty slice at the desired location:

11.8. List deletion

Using slices to delete list elements can be error-prone. Python provides an alternative that is more readable. The del statement removes an element from a list:

As you might expect, del causes a runtime error if the index is out of range.

You can also use del with a slice to delete a sublist:

As usual, the sublist selected by slice contains all the elements up to, but not including, the second index.

11.9. Glossary and Exercises

The glossary and exercises for this chapter are included at the end of Chapter 11 - Lists - Part B