3.4.1. Lists

Lists are sequences of things. What kinds of things? Well, anything that can be a thing in Python. That is one key fact about lists. A list can be a higgledypiggledy assortment. One list can contain a number, a string, and another list. You should certainly use lists when you want to remember the order in which you saw a sequence of things. But there are other reasons to use lists. They are in some ways the default container type.

Python uses square brackets to enclose lists and commas to separate the elements, so X, Y, and Z are all valid lists:

>>> X = [24, 3.14, 'w', [1,'a']] #  List with 4 items
>>> Y = [100]    # list with one item
>>> Z = [] #empty list

Note in particular that one of the elements of X is itself a list. More on lists containing lists below. The name list is special in Python, because it refers to the type list:

>>> list
<type 'list'>

3.4.1.1. Creating lists

You can use the type name as function of to create lists. So consider the following:

>>> L = list('hi!')

Python interprets this as a request to make a list that contains the same things as the string hi!; that string contains 3 characters, so Python makes L be a list containing three characters:

>>> L
['h', 'i', '!']

Use of the the type as a function that creates instances of the type is a standard practice in Python, so the list function can be fed any sequence as an argument, and it returns a list containing the same elements. A special case is calling list with no arguments at all:

>>> M = list()

This returns a special list called the empty list, which is of length 0, and contains no elements at all:

>>> M
[]

This may seem useless, but it is a great convenience when programming the result be something that is well defined and legal when all the elements have been removed from a list.

3.4.1.2. Indexing lists, list slices

A list is an index where the indices are numbers; items are referred to by their integer indices:

>>> X[0]   # 1st element
24
>>> X[1]   # 2nd element
3.14
>>> X[-1]   # last element
[1,'a']

Thus, indexing starts with 0. This means the highest index that retrieves anything is 1 less than the length of the list. List X has length 4, so the following raises an IndexError:

>>> X[4]   # Raises exception!
...
IndexError: list index out of range

Python also provides easy access to subsequences of a list. The following examples illustrate how to make such references:

>>> X[0:2] # list of 1st and 2nd elements
[24, 3.14]
>>> X[:-1] # list excluding last element

References to subsequences of a list are called slices.

List can be concatenated to make longer lists:

>>> X + Y # Concatenation!
[24, 3.14, 'w', [1,'a'], 100]

Lists allow value assignments, which change the value of a reference in place (in place assignment):

>>> X[2] = 5
>>> X
[24, 3.14, 5, [1,'a']]
>>> X[0:2]
[24, 3.14]

Slices can also be assigned to:

>>> X[0:2] = [1,3]
>>> X
[1, 3, 5, [1,'a']]

Only list-values can be assigned to slices:

>>> X[0:2] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable

The Error message here “TypeError: can only assign an iterable” refers to a general class containing containers called iterables, the root of the the tree in the Section on More Python types. We’ll talk more about iterables later. The important point for now is that iterables include all containers (including lists), but not integers, so:

>>> X[0:2] = [1]

works, but

>>> X[0:2] = 1

does not. A list slice must be filled in by a list; any iterable can be easily turned into a list, but 1 cannot.

Learning how to read and interpret Python errors is an important part of being able to write simple programs in Python. Properly understood, Python’s error-reporting will make it easier for you to fix errors.

As we noted in introducing Python containers, you can check whether something is among the elements of a container by using the operator in.

Note

in is called an operator because it can occur in between its arguments.

Using in on X we find:

>>> 24 in X
True
>>> 6 in X
False

A second property common to all containers is length. To find the length of any container we use the function len:

>>> X = [24, 3.14, 'w', [1,'a']] #  List with 4 items
>>> len(X)
4

Note X has 4 elements, not 5. The last element is a list of length 2:

>>> len(X[-1])
2

3.4.1.3. Changing the beginning and end of a list

An important routine task in computing is building up a list element by element. For example, we might be looking for all months with an r in them. Typically we would compute that by working our way through each month m, checking to see if there is an r in m’s name, and if there is, adding m to a result list.

Suppose we had worked our way through the first 4 months and our result list result looked like this:

>>> result
['January', 'February', 'March', 'April']

Here’s what we might do, once we discovered May belongs on the list:

>>> result.append('May')
>>> result
['January', 'February', 'March', 'April', 'May']

This puts September at the end of the list. The following does not do what we want:

>>> result + ['May']
['January', 'February', 'March', 'April','May']
>>> result
['January', 'February', 'March', 'April']

Although concatenating the lists returns the list we want, it does not change the value of result. So this is an important way in which append and concatenation (+) differ. To get what we want with +, we must do:

>>> result = result + ['May']

Although there are occasions when concatenation is convenient (for example, when joining two long lists), it is less efficient than appending.

To place September before the second element of result instead, we could have used insert:

>>> result.insert(1,'May')
>>> result
['January', 'May', 'February', 'March', 'April']

The rule is: Inserting x at index :samp:`i make x the new member with index i. So:

>>> result.insert(len(result),'May')

is equivalent to:

>>> result.append('May')

Finally, we sometimes need to remove things from lists. If we want to remove the last item, a builtin function called pop works:

>>> result
['January', 'February', 'March', 'April', 'May']
>>> result.pop()
'May'
>>> result
['January', 'February', 'March', 'April']

If we want to remove the second item, pop also works:

>>> result
['January', 'February', 'March', 'April', 'May']
>>> result.pop(1)
'February'
>>> result
['January', 'March', 'April', 'May']

If we want to remove a specific item whose position is unknown, we use remove:

>>> result
['January', 'February', 'March', 'April', 'May']
>>> result.remove('February')
>>> result
['January', 'March', 'April', 'May']

Now let’s say we have a list of months we want to remove something from, and we know two things. We know the element we want to remove is ‘May’ and we know it’s the last thing on the list. Which method should we use, remove or pop? Or does it matter?

It matters little in this instance, but in principle we should use pop. It’s more efficient. The first thing remove has to do is to search through the list to find where in it ‘May’ occurs. Only then can it perform the right update on the list. This could take quite a while if, say, the list, is 1,000,000 elements long and ‘May’ is the last thing on it. Meanwhile, pop involves no search. It just removes the element at a particular index.

3.4.1.4. Lists containing lists

We introduced the list structure by saying a list could contain anything. That includes a list. Lists of lists are useful for many purposes. One of the most intuitive is to represent a table. Suppose we want to represent the following table from some dataset in Python.

\begin{array}[t]{ccc}
 42 & 3.14 & 7 \\
 2 & 4 & 0 \\
 14 & 0 & 0
 \end{array}

We can do that as follows:

>>> Table = [[42, 3.14,7],[2,4,0],[14,0,0]]
>>> Table[0]
[42, 3.14,7]

This means to retrieve the value 42, we can do:

>>> FirstRow = Table[0]
>>> FirstRow[0]
42

But Python allows any expression which has a list as its value to be followed by [index]. That includes the expression Table[0]. It is much more convenient and Pythonic to do this in one step:

>>> Table[0][0]
42

So in general, thinking of a table as a list of rows, each of which is a list, we can access the element in row i, column j, with Table[i][j].

3.4.1.5. List operators, methods, and functions

In all the following examples, L is a list. Many of the following operators, methods, and functions are covered in the discussions above. A few are new, but useful.

len(L)

Returns length of L.

x in L

Returns True if x is in L. Otherwise returns False.

L.insert(i, x)

Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).

L.append(x)

Equivalent to a.insert(len(a), x).

L.index(x)

Return the index in the list of the first item whose value is x. It is an error if there is no such item.

L.remove(x)

Remove the first item from the list whose value is x. It is an error if there is no such item.

L.sort()

Sort the items of the list. Much more to be said about this. But it changes the list.

L.reverse()

Reverse the elements of the list, in place.

L.count(x)

Return the number of times x appears in the list.

See also

Beginners will find Enthought’s introductory lectures on Python, entitled Python Essentials, very useful. Users with an Academic license have free access to these lectures. For a alternative nice overview of list operations, see the Google’s tutorial. This is geared toward the more advanced student. For a real programmer’s discussion of Python lists, addressing questions like what’s faster, assignment or insertion, or what’s faster, insertion at the beginning, or insertion at the end, see Fredrik Lundh’s effbot.org discussion.