Sequences
The main sequence types in Python are lists, tuples and range objects. The main differences between these sequence objects are:
- Lists are mutable and their elements are usually homogeneous (things of the same type making a list of similar objects)
- Tuples are immutable and their elements are usually heterogeneous (things of different types making a tuple describing a single structure)
- Range objects are efficient sequences of integers (commonly used in
for
loops), use a small amount of memory and yield items only when needed
Lists
Create a list using square brackets [ ... ]
with items separated by commas. For example, create a list of square integers, assign it to a variable and use the built-in function print()
to display the list:
squares = [1,4,9,16,25]
print(squares)
[1, 4, 9, 16, 25]
Lists may contain data of any type including other lists:
points = [[0,0],[0,1],[1,1],[0,1]]
print(points)
[[0, 0], [0, 1], [1, 1], [0, 1]]
Index
Access the elements of a list by their index:
primes = [2,3,5,7,11,13,17,19,23,29]
print(primes[0])
2
Notice that lists are indexed starting at 0:
print(primes[1])
print(primes[2])
print(primes[6])
3
5
17
Use negative indices to access elements starting from the end of the list:
print(primes[-1])
print(primes[-2])
29
23
Since lists are mutable, we may assign new values to entries in a list:
primes[0] = -1
print(primes)
[-1, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Use multiple indices to access entries in a list of lists:
pairs = [[0,1],[2,3],[4,5],[6,7]]
print(pairs[2][1])
5
Slice
Create a new list from a sublist (called a slice):
fibonacci = [1,1,2,3,5,8,13,21,34,55,89,144]
print(fibonacci[4:7])
print(fibonacci[6:])
print(fibonacci[:-2])
[5, 8, 13]
[13, 21, 34, 55, 89, 144]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Notice in the example fibonacci[4:7]
the slice begins at index 4 and goes up to but not including index 7. This makes sense since the length of the slice is then 7 - 4 = 3.
A slice can skip over entries in a list. For example, create a slice from every third entry from index 0 to 11:
print(fibonacci[0:11:3])
[1, 3, 13, 55]
Concatenate
The addition operator +
concatenates lists:
one = [1]
two = [2,2]
three = [3,3,3]
numbers = one + two + three
print(numbers)
[1, 2, 2, 3, 3, 3]
Append
Add a value to the end of a list using the append()
list method:
squares = [1,4,9,16,25]
squares.append(36)
print(squares)
[1, 4, 9, 16, 25, 36]
What is an object method? First, an object in Python (such as a list) contains data as well as functions (called methods) to manipulate that data. Everything in Python is an object! The list squares
in the cell above contains the integer entries (the data) but it also has methods like append()
to manipulate the data. We'll see more about objects and methods later on. For now, see the documentation for a complete list of list methods.
Tuples
Create a tuple with parentheses ( ... )
:
triple = (5,12,13)
print(triple)
(5, 12, 13)
Indexing, slicing and concatenating work for tuples in the exact same way as for lists:
print(triple[0])
print(triple[-1])
print(triple[1:3])
5
13
(12, 13)
Range Objects
Create a range object with the built-in function range()
. The parameters a
, b
and step
in range(a,b,step)
are integers and the function creates an object which represents the sequence of integers from a
to b
(exclusively) incremented by step
. (The parameter step
may be omitted and is equal to 1 by default.)
digits_range = range(0,10)
print(digits_range)
range(0, 10)
Notice that a range object does not display the values of its entries when printed. This is because a range object is an efficient sequence which yields values only when needed.
Use the built-in function list()
to convert a range object to a list:
digits_range = range(0,10)
digits_list = list(digits_range)
print(digits_list)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Create a range of even integers and convert it to a list:
even_list = list(range(0,10,2))
print(even_list)
[0, 2, 4, 6, 8]
Unpacking a Sequence
One of the features of a Python sequence is unpacking where we assign all the entries of a sequence to variables in a single operation. For example, create a tuple representing a date and unpack the data as year
, month
and and day
:
triple = (5,12,13)
x,y,z = triple
print(x)
print(y)
print(z)
5
12
13
List Comprehensions
The built-in function range()
is an efficient tool for creating sequences of integers but what about an arbitrary sequence? It is very inefficient to create a sequence by manually typing the numbers. For example, simply typing out the numbers from 1 to 20 takes a long time!
numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Python has a beautiful syntax for creating lists called list comprehensions. The syntax is:
[expression for item in iterable]
where:
iterable
is a range, list, tuple, or any kind of sequence objectitem
is a variable name which takes each value in the iterableexpression
is a Python expression which is calculated for each value ofitem
Use a list comprehension to create the list from 1 to 20:
numbers = [n for n in range(1,21)]
print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Create the list of square integers from $1$ to $100$:
squares = [n**2 for n in range(1,11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Create the periodic sequence $0,1,2,0,1,2,0,1,2,\dots$ of length 21 (using the remainder operator %
):
zero_one_two = [n%3 for n in range(0,21)]
print(zero_one_two)
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
Built-in Functions for Sequences
Python has several built-in functions for computing with sequences. For example, compute the length of a list:
len([1,2,3])
3
Compute the sum, maximum and minimum of a list of numbers:
random = [3,-5,7,8,-1]
print(sum(random))
print(max(random))
print(min(random))
12
8
-5
Sort the list:
sorted(random)
[-5, -1, 3, 7, 8]
Sum the numbers from 1 to 100:
one_to_hundred = range(1,101)
print(sum(one_to_hundred))
5050
Examples
Triangular Numbers
The formula for the sum of integers from 1 to $N$ (also known as triangular numbers) is given by:
$$ \sum_{k=1}^N k = \frac{N(N+1)}{2} $$
Let's verify the formula for $N=1000$:
N = 1000
left_side = sum([k for k in range(1,N+1)])
right_side = N*(N+1)/2
print(left_side)
print(right_side)
500500
500500.0
Notice the results agree (although the right side is a float since we used division).
Sum of Squares
The sum of squares (a special case of a geometric series) is given by the formula:
$$ \sum_{k=1}^N k^2 = \frac{N(N+1)(2N+1)}{6} $$
Let's verify the formula for $N=2000$:
N = 2000
left_side = sum([k**2 for k in range(1,N+1)])
right_side = N*(N+1)*(2*N+1)/6
print(left_side)
print(right_side)
2668667000
2668667000.0
Riemann Zeta Function
The Riemann zeta function is the infinite series:
$$ \zeta(s) = \sum_{n=1}^{\infty} \frac{1}{n^s} $$
Its values are very mysterious! Let's verify the special value formula:
$$ \zeta(4) = \sum_{n=1}^{\infty} \frac{1}{n^4} = \frac{\pi^4}{90} $$
Compute the 1000th partial sum of the series:
terms = [1/n**4 for n in range(1,1001)]
sum(terms)
1.082323233378306
Compare to an approximation of $\frac{\pi^4}{90}$:
3.14159**4/90
1.082319576918468
Exercises
Exercise 1. The Maclaurin series of $\arctan(x)$ is:
$$ \arctan(x) = \sum_{n = 0}^{\infty} \frac{(-1)^nx^{2n + 1}}{2n+1} $$
Substituting $x = 1$ gives a series representation of $\pi/4$. Compute the partial sum up to $N=5000$ to approximate:
$$ \frac{\pi}{4} \approx \sum_{n = 0}^{5000} \frac{(-1)^nx^{2n + 1}}{2n+1} $$
Exercise 2. Compute the partial sum of the alternating harmonic series:
$$\sum_{n=1}^{2000}\frac{(-1)^{n+1}}{n}$$
Exercise 3. Write a list comprehension to create the list of lists:
[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49]]