76
90
Chapter 4
>>> spam
['cat', 'dog', 'bat', 'moose']
The previous
append()
method call adds the argument to the end of
the list. The
insert()
method can insert a value at any index in the list.
The first argument to
insert()
is the index for the new value, and the sec-
ond argument is the new value to be inserted. Enter the following into the
interactive shell:
>>> spam = ['cat', 'dog', 'bat']
>>> spam.insert(1, 'chicken')
>>> spam
['cat', 'chicken', 'dog', 'bat']
Notice that the code is
spam.append('moose')
and
spam.insert(1, 'chicken')
,
not
spam = spam.append('moose')
and
spam = spam.insert(1, 'chicken')
. Neither
append()
nor
insert()
gives the new value of
spam
as its return value. (In fact,
the return value of
append()
and
insert()
is
None
, so you definitely wouldn’t
want to store this as the new variable value.) Rather, the list is modified in
place. Modifying a list in place is covered in more detail later in “Mutable
and Immutable Data Types” on page 94.
Methods belong to a single data type. The
append()
and
insert()
methods
are list methods and can be called only on list values, not on other values
such as strings or integers. Enter the following into the interactive shell,
and note the
AttributeError
error messages that show up:
>>> eggs = 'hello'
>>> eggs.append('world')
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
eggs.append('world')
AttributeError: 'str' object has no attribute 'append'
>>> bacon = 42
>>> bacon.insert(1, 'world')
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
bacon.insert(1, 'world')
AttributeError: 'int' object has no attribute 'insert'
Removing Values from Lists with remove()
The
remove()
method is passed the value to be removed from the list it is
called on. Enter the following into the interactive shell:
>>> spam = ['cat', 'bat', 'rat', 'elephant']
>>> spam.remove('bat')
>>> spam
['cat', 'rat', 'elephant']
57
Lists
91
Attempting to delete a value that does not exist in the list will result in
a
ValueError
error. For example, enter the following into the interactive shell
and notice the error that is displayed:
>>> spam = ['cat', 'bat', 'rat', 'elephant']
>>> spam.remove('chicken')
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
spam.remove('chicken')
ValueError: list.remove(x): x not in list
If the value appears multiple times in the list, only the first instance of
the value will be removed. Enter the following into the interactive shell:
>>> spam = ['cat', 'bat', 'rat', 'cat', 'hat', 'cat']
>>> spam.remove('cat')
>>> spam
['bat', 'rat', 'cat', 'hat', 'cat']
The
del
statement is good to use when you know the index of the value
you want to remove from the list. The
remove()
method is good when you
know the value you want to remove from the list.
Sorting the Values in a List with the sort() Method
Lists of number values or lists of strings can be sorted with the
sort()
method. For example, enter the following into the interactive shell:
>>> spam = [2, 5, 3.14, 1, -7]
>>> spam.sort()
>>> spam
[-7, 1, 2, 3.14, 5]
>>> spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants']
>>> spam.sort()
>>> spam
['ants', 'badgers', 'cats', 'dogs', 'elephants']
You can also pass
True
for the
reverse
keyword argument to have
sort()
sort the values in reverse order. Enter the following into the interactive shell:
>>> spam.sort(reverse=True)
>>> spam
['elephants', 'dogs', 'cats', 'badgers', 'ants']
There are three things you should note about the
sort()
method. First,
the
sort()
method sorts the list in place; don’t try to capture the return
value by writing code like
spam = spam.sort()
.
56
92
Chapter 4
Second, you cannot sort lists that have both number values and string
values in them, since Python doesn’t know how to compare these values.
Type the following into the interactive shell and notice the
TypeError
error:
>>> spam = [1, 3, 2, 4, 'Alice', 'Bob']
>>> spam.sort()
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
spam.sort()
TypeError: unorderable types: str() < int()
Third,
sort()
uses “ASCIIbetical order” rather than actual alphabetical
order for sorting strings. This means uppercase letters come before lower-
case letters. Therefore, the lowercase a is sorted so that it comes after the
uppercase Z. For an example, enter the following into the interactive shell:
>>> spam = ['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
>>> spam.sort()
>>> spam
['Alice', 'Bob', 'Carol', 'ants', 'badgers', 'cats']
If you need to sort the values in regular alphabetical order, pass
str.
lower
for the
key
keyword argument in the
sort()
method call.
>>> spam = ['a', 'z', 'A', 'Z']
>>> spam.sort(key=str.lower)
>>> spam
['a', 'A', 'z', 'Z']
This causes the
sort()
function to treat all the items in the list as if they
were lowercase without actually changing the values in the list.
example Program: magic 8 Ball with a list
Using lists, you can write a much more elegant version of the previous chap-
ter’s Magic 8 Ball program. Instead of several lines of nearly identical
elif
statements, you can create a single list that the code works with. Open a new
file editor window and enter the following code. Save it as magic8Ball2.py.
import random
messages = ['It is certain',
'It is decidedly so',
'Yes definitely',
'Reply hazy try again',
'Ask again later',
'Concentrate and ask again',
'My reply is no',
'Outlook not so good',
'Very doubtful']
print(messages[random.randint(0, len(messages) - 1)])
54
Lists
93
When you run this program, you’ll see that it works the same as the
previous magic8Ball.py program.
Notice the expression you use as the index into
messages
:
random
.randint(0, len(messages) - 1)
. This produces a random number to use
for the index, regardless of the size of
messages
. That is, you’ll get a ran-
dom number between
0
and the value of
len(messages) - 1
. The benefit of
this approach is that you can easily add and remove strings to the
messages
list without changing other lines of code. If you later update your code,
there will be fewer lines you have to change and fewer chances for you to
introduce bugs.
list-like types: Strings and tuples
Lists aren’t the only data types that represent ordered sequences of values.
For example, strings and lists are actually similar, if you consider a string to
be a “list” of single text characters. Many of the things you can do with lists
exCePtio nS to inDentAtion ruleS in Py thon
In most cases, the amount of indentation for a line of code tells Python what
block it is in There are some exceptions to this rule, however For example, lists
can actually span several lines in the source code file The indentation of these
lines do not matter; Python knows that until it sees the ending square bracket,
the list is not finished For example, you can have code that looks like this:
spam = ['apples',
'oranges',
'bananas',
'cats']
print(spam)
Of course, practically speaking, most people use Python’s behavior to
make their lists look pretty and readable, like the messages list in the Magic 8
Ball program
You can also split up a single instruction across multiple lines using the
\
line continuation character at the end Think of
\
as saying, “This instruction
continues on the next line” The indentation on the line after a
\
line continua-
tion is not significant For example, the following is valid Python code:
print('Four score and seven ' + \
'years ago...')
These tricks are useful when you want to rearrange long lines of Python
code to be a bit more readable
54
94
Chapter 4
can also be done with strings: indexing; slicing; and using them with
for
loops, with
len()
, and with the
in
and
not in
operators. To see this, enter the
following into the interactive shell:
>>> name = 'Zophie'
>>> name[0]
'Z'
>>> name[-2]
'i'
>>> name[0:4]
'Zoph'
>>> 'Zo' in name
True
>>> 'z' in name
False
>>> 'p' not in name
False
>>> for i in name:
print('* * * ' + i + ' * * *')
* * * Z * * *
* * * o * * *
* * * p * * *
* * * h * * *
* * * i * * *
* * * e * * *
Mutable and Immutable Data Types
But lists and strings are different in an important way. A list value is a mutable
data type: It can have values added, removed, or changed. However, a string
is immutable: It cannot be changed. Trying to reassign a single character in
a string results in a
TypeError
error, as you can see by entering the following
into the interactive shell:
>>> name = 'Zophie a cat'
>>> name[7] = 'the'
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
name[7] = 'the'
TypeError: 'str' object does not support item assignment
The proper way to “mutate” a string is to use slicing and concatenation
to build a new string by copying from parts of the old string. Enter the fol-
lowing into the interactive shell:
>>> name = 'Zophie a cat'
>>> newName = name[0:7] + 'the' + name[8:12]
>>> name
'Zophie a cat'
52
Lists
95
>>> newName
'Zophie the cat'
We used
[0:7]
and
[8:12]
to refer to the characters that we don’t wish
to replace. Notice that the original
'Zophie a cat'
string is not modified
because strings are immutable.
Although a list value is mutable, the second line in the following code
does not modify the list
eggs
:
>>> eggs = [1, 2, 3]
>>> eggs = [4, 5, 6]
>>> eggs
[4, 5, 6]
The list value in
eggs
isn’t being changed here; rather, an entirely new
and different list value (
[4, 5, 6]
) is overwriting the old list value (
[1, 2, 3]
).
This is depicted in Figure 4-2.
If you wanted to actually modify the original list in
eggs
to contain
[4, 5, 6]
, you would have to do something like this:
>>> eggs = [1, 2, 3]
>>> del eggs[2]
>>> del eggs[1]
>>> del eggs[0]
>>> eggs.append(4)
>>> eggs.append(5)
>>> eggs.append(6)
>>> eggs
[4, 5, 6]
Figure 4-2: When eggs = [4, 5, 6] is executed, the contents of eggs are replaced with a
new list value.
In the first example, the list value that
eggs
ends up with is the same
list value it started with. It’s just that this list has been changed, rather than
overwritten. Figure 4-3 depicts the seven changes made by the first seven
lines in the previous interactive shell example.
47
96
Chapter 4
Figure 4-3: The del statement and the append() method modify the same list value
in place.
Changing a value of a mutable data type (like what the
del
statement
and
append()
method do in the previous example) changes the value in
place, since the variable’s value is not replaced with a new list value.
Mutable versus immutable types may seem like a meaningless dis-
tinction, but “Passing References” on page 100 will explain the different
behavior when calling functions with mutable arguments versus immu-
table arguments. But first, let’s find out about the tuple data type, which is
an immutable form of the list data type.
The Tuple Data Type
The tuple data type is almost identical to the list data type, except in two
ways. First, tuples are typed with parentheses,
(
and
)
, instead of square
brackets,
[
and
]
. For example, enter the following into the interactive shell:
>>> eggs = ('hello', 42, 0.5)
>>> eggs[0]
'hello'
>>> eggs[1:3]
(42, 0.5)
>>> len(eggs)
3
But the main way that tuples are different from lists is that tuples,
like strings, are immutable. Tuples cannot have their values modified,
appended, or removed. Enter the following into the interactive shell, and
look at the
TypeError
error message:
>>> eggs = ('hello', 42, 0.5)
>>> eggs[1] = 99
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
eggs[1] = 99
TypeError: 'tuple' object does not support item assignment
Documents you may be interested
Documents you may be interested