9.1 Mutability and tuples
So far, you have seen two compound types: strings, which are made up of characters; and lists, which are made up of elements of any type. One of the differences we noted is that the elements of a list can be modified, but the characters in a string cannot. In other words, strings are immutable and lists are mutable.
There is another type in Python called a tuple that is similar to a list except that it is immutable. Syntactically, a tuple is a comma-separated list of values:
>>> tuple = 'a', 'b', 'c', 'd', 'e'
Although it is not necessary, it is conventional to enclose tuples in parentheses:
>>> tuple = ('a', 'b', 'c', 'd', 'e')
To create a tuple with a single element, we have to include the final comma:
>>> t1 = ('a',)
>>> type(t1)
<type 'tuple'>
Without the comma, Python treats ('a') as a string in parentheses:
>>> t2 = ('a')
>>> type(t2)
<type 'str'>
Syntax issues aside, the operations on tuples are the same as the operations on lists. The index operator selects an element from a tuple.
>>> tuple = ('a', 'b', 'c', 'd', 'e')
>>> tuple[0]
'a'
And the slice operator selects a range of elements.
>>> tuple[1:3]
('b', 'c')
But if we try to modify one of the elements of the tuple, we get an error:
>>> tuple[0] = 'A'
TypeError: object doesn't support item assignment
Of course, even if we can't modify the elements of a tuple, we can replace it with a different tuple:
>>> tuple = ('A',) + tuple[1:]
>>> tuple
('A', 'b', 'c', 'd', 'e')
9.2 Tuple assignment
Once in a while, it is useful to swap the values of two variables. With conventional assignment statements, we have to use a temporary variable. For example, to swap a and b:
>>> temp = a
>>> a = b
>>> b = temp
If we have to do this often, this approach becomes cumbersome. Python provides a form of tuple assignment that solves this problem neatly:
>>> a, b = b, a
The left side is a tuple of variables; the right side is a tuple of values. Each value is assigned to its respective variable. All the expressions on the right side are evaluated before any of the assignments. This feature makes tuple assignment quite versatile.
Naturally, the number of variables on the left and the number of values on the right have to be the same:
>>> a, b, c, d = 1, 2, 3
ValueError: unpack tuple of wrong size
9.3 Tuples as return values
Functions can return tuples as return values. For example, we could write a function that swaps two parameters:
def swap(x, y):
return y, x
Then we can assign the return value to a tuple with two variables:
a, b = swap(a, b)
In this case, there is no great advantage in making swap a function. In fact, there is a danger in trying to encapsulate swap, which is the following tempting mistake:
def swap(x, y): # incorrect version
x, y = y, x
If we call this function like this:
swap(a, b)
then a and x are aliases for the same value. Changing x inside swap makes x refer to a different value, but it has no effect on a in __main__. Similarly, changing y has no effect on b.
This function runs without producing an error message, but it doesn't do what we intended. This is an example of a semantic error.
9.4 Random numbers
Most computer programs do the same thing every time they execute, so they are said to be deterministic. Determinism is usually a good thing, since we expect the same calculation to yield the same result. For some applications, though, we want the computer to be unpredictable. Games are an obvious example, but there are more.
Making a program truly nondeterministic turns out to be not so easy, but there are ways to make it at least seem nondeterministic. One of them is to generate random numbers and use them to determine the outcome of the program. Python provides a module that generates pseudorandom numbers.
The random module contains a function called random that returns a floating-point number between 0.0 and 1.0. Each time you call random, you get the next number in a long series. To see a sample, run this loop:
import random
for i in range(10):
x = random.random()
print x
To generate a random number between 0.0 and an upper bound like high, multiply x by high.
Try This:
Pt1: As an exercise, generate a random number between low and high.
Pt2: As an additional exercise, generate a random integer between low and
high, including both end points.
Solutions
9.5 List of random numbers
The first step is to generate a list of random values. randomList takes an integer argument and returns a list of random numbers with the given length. It starts with a list of n zeros. Each time through the loop, it replaces one of the elements with a random number. The return value is a reference to the complete list:
def randomList(n):
s = [0] * n
for i in range(n):
s[i] = random.random()
return s
We'll test this function with a list of eight elements. For purposes of debugging, it is a good idea to start small.
>>> randomList(8)
[0.15156642489,
0.498048560109,
0.810894847068,
0.360371157682,
0.275119183077,
0.328578797631,
0.759199803101,
0.800367163582]
The numbers generated by random are supposed to be distributed uniformly, which means that every value is equally likely.
The random module also includes an option for generating random value from a sequence. choice is the method for doing this.
>>>import random
>>>suits = ['hearts', 'spades', 'clubs', 'diamonds']
>>>random.choice(suits)
'clubs'
>>>random.choice(suits)
'hearts'
>>>random.choice('abcdefg')
'f'
There are many more methods in the random module. Find the "Random Module" link on the left side of this page to find a method that fits your specific need.
9.9 Glossary
immutable type
A type in which the elements cannot be modified. Assignments to elements or
slices of immutable types cause an error.
mutable type
A data type in which the elements can be modified. All mutable types are
compound types. Lists and dictionaries are mutable data types; strings and tuples
are not.
tuple
A sequence type that is similar to a list except that it is immutable. Tuples can be
used wherever an immutable type is required, such as a key in a dictionary.
tuple assignment
An assignment to all of the elements in a tuple using a single assignment
statement. Tuple assignment occurs in parallel rather than in sequence, making it
useful for swapping values.
deterministic
A program that does the same thing each time it is called.
pseudorandom
A sequence of numbers that appear to be random but that are actually the result of a deterministic computation.
histogram
A list of integers in which each element counts the number of times something happens.
pattern matching
A program development plan that involves identifying a familiar computational pattern and copying the solution to a similar problem.