0% found this document useful (0 votes)
5 views

Python3 Notes

Uploaded by

khmfbbnc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Python3 Notes

Uploaded by

khmfbbnc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 216

Other methods on lists: sort()

>>> numbers = [4, 7, 5, 1]

>>> numbers.sort()
The function does not
return the sorted list.
>>> print(numbers)
It sorts the
[1, 4, 5, 7]
list itself.

Numerical order.

215

Similarly, the sort() method doesn’t return a sorted list but silently sorts
the list internally.

215
Other methods on lists: sort()

>>> greek = ['alpha', 'beta', 'gamma', 'delta']

>>> greek.sort()

>>> print(greek)

['alpha', 'beta', 'delta', 'gamma']

Alphabetical order
of the words.
216

More or less any type can be sorted. Text sorting carries all the cautions
about the complexities of collation that we covered under comparisons.

216
Other methods on lists: insert()
0 1 2

>>> greek = ['alpha', 'gamma', 'delta']

>>> greek.insert(1, 'beta' )

Where to insert What to insert

>>> greek

['alpha', 'beta', 'gamma', 'delta']

0 1
Displaced 217

The append() method sticks an item on the end of a list. If you want to
insert an item elsewhere in the list we have the insert() method.
The insert() method takes two arguments:
The first is the item to be inserted.
The second is in index where it should go. This does not replace the original
item but rather “shuffles up” all the items beyond it by one place to make
room.

217
Other methods on lists: remove()

>>> numbers = [7, 4, 8, 7, 2, 5, 4]

>>> numbers.remove(8) Value to remove

>>> print(numbers)

[7, 4, 7, 2, 5, 4]

c.f. del numbers[2] Index to remove 218

There is a remove() method.


This is passed a value to remove from the list. It then removes that value
from the list, wherever it is in the list.
Contrast with with del where you had to know the index to remove.

218
Other methods on lists: remove()

>>> print(numbers)

[7, 4, 7, 2, 5, 4]
There are two instances of 4.
>>> numbers.remove(4)

>>> print(numbers)

[7, 7, 2, 5, 4]

Only the first instance is removed 219

If the value appears more than once in a list then only the first instance is
removed.
Trying to remove something that isn’t there will lead to an error.

219
What methods are there?
>>> help(numbers)

Help on list object:

class list(object)
...
| append(...)
| L.append(object) -- append object to end
...

Pagination: ␣ next page

B back one page


220
Q quit

That’s a lot of methods, and it’s only some of them. How can we know all of
them?
You can always ask for help on any Python object and you will be told all
about the methods it possesses. It is a very formal documentation but the
information is there.
Incidentally, Python uses a program to paginate its help output. press the
space bar to move on one page, “B” to move back a page and “Q” to quit.

220
Help on a single method
>>> help(numbers.append)

Help on built-in function append:

append(...)
L.append(object) -- append object to end

221

You can also get help on a single method which is often simpler to deal with.

221
Sorting a list redux

>>> greek = ['alpha', 'beta', 'gamma', 'delta']

>>> greek.sort() Recall: greek.sort()


sorts the list “in place”.

>>> print(greek)

['alpha', 'beta', 'delta', 'gamma']

222

We noted that the sort() method sorts the list itself. Experience shows that
sorting is one of those operations where people want a sorted copy of the
list quite often.

222
Sorting a list redux: “sorted()”

>>> greek = ['alpha', 'beta', 'gamma', 'delta']

>>> print(sorted(greek)) sorted() function


returns a sorted list…
['alpha', 'beta', 'delta', 'gamma']

>>> print(greek) …and leaves the


list alone
['alpha', 'beta', 'gamma', 'delta']
223

To assist with this, Python 3 offers a standalone function called sorted()


which makes a copy of the list and sorts that copy, leaving the original
unchanged.

223
Adding to a list redux: “+”

>>> primes

[2, 3, 5, 7, 11, 13, 17, 19]

Concatenation List to add


operator

>>> primes + [23, 29, 31]

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]

224

The list method we saw first appended a single item to the end of a list.
What happens if we want to add a whole list of items at the end?
In this regard, lists are like strings. The “+” operator performs concatenation
and creates a new list which is one concatenated after the other.

224
Concatenation
Create a new list

>>> newlist = primes + [23, 29, 31]

Update the list

>>> primes = primes + [23, 29, 31]

Augmented assignment

>>> primes += [23, 29, 31]

225

We can use this to update a list in place. Note that the augmented
assignment operator “+=” also works and is more than syntactic sugar this
time. It is actually more efficient than the long hand version because it
updates the list in place rather than creating a new one.

225
Creating lists from text ― 1

>>> list('Hello') str 1 H

['H', 'e', 'l', 'l', 'o'] list


str 1 e
5

str 5 H e l l o str 1 l

str 1 l

str 1 o
226

We ought to look at a couple of ways to create lists from text.


The first is to simply convert a string into a list with the list() function.
(As with all Python types, there is a function of the same name as the type
that converts into the type.)
Applying list() to a string gives a list of the characters in the string.

226
Creating lists from text ― 2
Built in method
>>> 'Hello, world!'.split()

['Hello,', 'world!'] Splits on spaces

str 13 H e l l o , ␣ w o r l d !

list
2 str 6 H e l l o ,

str 6 w o r l d !
227

The string type has methods of its own. One of these is split() which returns
a list of the components of the string as separated by white space.
The split() method can take an argument identifying other characters to
split on. If you want to get into more complex splitting of text we recommend
you investigate regular expressions or format-specific techniques (e.g. for
comma-separated values.

227
Progress
“Methods” object.method(arguments)
append(item)
reverse()
sort()
insert(index,item)
remove(item)

Help help(object)
help(object.method)

Sorting list.sort()
sorted(list)
Concatenation
+ [1,2,3] + [4,5,6] 228
+= primes += [29, 31]

228
Exercise 12

5 minutes
229

229
Is an item in a list? ― 1

>>> odds = [3, 5, 7, 9] Does not include 2

>>> odds.remove(2) Try to remove 2

Traceback (most recent call last): Hard error


File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

✗ x must be in the
list before it can
be removed
230

Recall that a list’s remove() method will give an error if the value to be
removed is not in the list to start with.
We need to be able to test for whether an item is in a list or not.

230
Is an item in a list? ― 2
>>> odds = [3, 5, 7, 9]

>>> 2 in odds

False

>>> 3 in odds

True

>>> 2 not in odds

True 231

Python uses the keyword “in” for this purpose. It can be used on its own or
as part of “not in”. “value in list” evaluates to a boolean: True or
False.

231
Precedence
First

x**y -x +x x%y x/y x*y x-y x+y

x==y x!=y x>=y x>y x<=y x<y

x not in y x in y

not x x and y x or y The list now contains


every operator we
Last meet in this course.
232

These operators fit naturally into the order of precedence. While Python
does contain other operators that belong in this list, we will not be meeting
them in this introductory course.

232
Safe removal

if number in numbers :

numbers.remove(number)

What’s the
difference?

while number in numbers :

numbers.remove(number)

233

We now have a safe way to remove values from lists, testing before we
remove them.
Quick question: What’s the difference between the two code snippets in the
slide?

233
Working through a list ― 1

e.g. Printing each element on a line

['The', 'cat', 'sat', 'on', 'the', 'mat.']

The
cat
sat
on
the
mat.
234

There is an obvious thing to want to do with a list, and that is to work


through each item in a list, in order, and perform some operation or set of
operations on each item.
In the most trivial case, we might want to print each item. The slide shows a
list of strings, probably from the split() of a string. How do we print each
item one after the other?

234
Working through a list ― 2

e.g. Adding the elements of a list

[45, 76, -23, 90, 15]

203

What is the sum of an empty list? [] ?

235

Alternatively, we might want to accumulate the items in a list in some way.


For example, we might want to sum the numbers in a list. This is another
example of applying an operation to each item in a list. This time the
operation is folding the list items’ values into some final result.
In this case we would probably need an initial value of the result that it takes
before any items get folded into it. What is the sum of an empty list? Zero?
Is that an integer zero, a floating point zero, or a complex zero?

235
Working through a list ― 3

e.g. Squaring every number in a list

[4, 7, -2, 9, 1]

[16, 49, 4, 81, 1]

236

Finally, we might want to convert one list into another where each item in the
output list is the result of some operation on the corresponding item in the
input list.

236
The “for loop” ― 1

name of list list

words = ['The', 'cat', 'sat', 'on', 'the', 'mat.']

for word in words : A new Python


looping construct
␣␣␣␣print(word)
print: What we want
to do with the list items.
237

Python has a construct precisely for stepping through the elements of a list.
This is the third and final construct we will meet in this course. We have
already seen if… and while… in this course. Now we meet for….
This a looping construct, but rather than repeat while a test evaluates to
True, it loops once for each item in a list. Furthermore it defines a name
which it attaches to one item after another in the list as it repeats the loop.

237
The “for loop” ― 2

words = ['The', 'cat', 'sat', 'on', 'the', 'mat.']

keywords

for word in words :


colon followed by
an indented block
␣␣␣␣print(word)

238

We'll look at the expression one step at a time.


The expression is introduced by the “for” keyword.
This is followed by the name of a variable. We will return to this in the next
slide.
After the name comes the keyword “in”. We have met this word in the
context of lists before when we tested for an item's presence in a list. This is
a different use. We aren't asking if a specific value is in a list but rather we
are asserting that we are going to be processing those values that are in it.
After this comes the list itself, or more often the name of a list. All it has to
be is an expression that evaluates to a list.
The line ends with a colon.
The lines following the colon are indented marking the block of code that is
to be run once for each item in the list.

238
The “for loop” ― 3

words = ['The', 'cat', 'sat', 'on', 'the', 'mat.']

Defining the loop variable

for word in words :

␣␣␣␣print(word)

Using the loop variable


239

Now let's return to the name between “for” and “in”.


This is called the “loop variable”. Each time the loop block is run this name
is attached to on item of the list. Each tim the loop is run the name is
attached to the next item in the list. The looping stops after the name has
been attached to the last item I nthe list.

239
The “for loop” for printing

words = ['The', 'cat', 'sat', 'on', 'the', 'mat.']

for word in words :

␣␣␣␣print(word)
for1.py

240

There is a simple example of this in the file for1.py in your home


directories.

$ python3 for1.py
The
cat
sat
on
the
mat.
$

240
The “for loop” for adding

numbers = [45, 76, -23, 90, 15]

sum = 0 Set up before the loop

for number in numbers :

␣␣␣␣sum += number Processing in the loop


for2.py

241
print(sum) Results after the loop

Our second case was an “accumulator” adding the elements in a list.


Here we establish an initial start value for our total of 0 and give it the name
“sum”.
Then we loop through the elements in the list, adding their values to the
running total as we move through them.
The unindented line after the loop block marks the end of the loop block and
is only run after all the looping is completed. This prints out the value of the
total now that all the numbers in the list have been added into it.

$ python3 for2.py
203
$

241
The “for loop” for creating a new list

numbers = [4, 7, -2, 9, 1]

squares = [ ] Set up before the loop

for number in numbers :

␣␣␣␣squares.append(number**2) Processing in the loop


for3.py

242
print(squares) Results after the loop

Our third example made a new list from the elements of an old list. For
example, we might want to take a list of numbers and produce the list of
their squares.
In this case the usual process is that rather than have an accumulator with
an initial value we start with an empty list and, as we loop through the input
values, we append() the corresponding output values.

$ python3 for3.py
[16, 49, 4, 81, 1]
$

242
The loop variable persists!
numbers = [4, 7, -2, 9, 1]

squares = [ ]

for number in numbers : Loop variable only


meant for use in loop!
␣␣␣␣squares.append(number**2)

print(number) But it persists!

243

There is one nicety we should observe.


The loop variable was created for the purpose of running through the
elements in the list. But it is just a Python name, no different from the ones
we establish by direct assignment. While the for… loop creates the name it
does not clean it up afterwards.

243
“for loop hygeine”
numbers = [4, 7, -2, 9, 1]

squares = [ ]

for number in numbers :

␣␣␣␣squares.append(number**2)

del number Delete it after use

244

It is good practice to delete the name after we have finished using it. So we
will follow our for… loops with a del statement.
This is not required by the Python language but we recommend it as good
practice.

244
Progress

Testing items in lists 3 in [1,2,3,4] True

for loops sum = 0


for number in [1,2,3,4]:
sum += number
del number

loop variables for number in [1,2,3,4]:


sum += number
del number
245

245
Exercise 13

What does this print?

numbers = [0, 1, 2, 3, 4, 5]

sum = 0
sum_so_far = []

for number in numbers:


sum += number
sum_so_far.append(sum)

print(sum_so_far) 5 minutes
246

246
“Sort-of-lists”

Python “magic”:

Treat it like a list and it will


behave like a useful list

What can “it” be?

247

We have seen already that every Python type comes with a function that
attempts to convert other Python objects into that type. So the list type
has a list() function.
However, with lists Python goes further and puts a lot of work into making
this transparent and convenient. In very many cases in Python you can drop
an object into a list construct and it will act as if it was a list, and a
convenient list at that.

247
Strings as lists

Recall:

list('Hello') ['H', 'e', 'l', 'l', 'o']

for letter in 'Hello' : H


print(letter) e
l
l
Gets turned o
for4.py
into a list.
248

For example, we know that if we apply the list() function to a string we


get the list of characters. But the Python “treat it like a list” magic means that
if we simply drop a string into the list slot in a for… loop then it is treated as
exactly that list of characters automatically.

$ python for4.py
H
e
l
l
o
$

248
Creating lists of numbers

Built in to Python:

range(start,limit)

for number in range(3,8): 3


print(number) 4
5
6
7
8 not included
249

There are other Python objects which, while not lists exactly, can be treated
like lists in a for… loop. A very important case is a “range” object.
Note that the range defined by 3 and 8 starts at 3 but ends one short. This is
part of the whole “count from zero” business.

249
ranges of numbers

Not actually lists: >>> range(0,5)

range(0,5)

But close enough: >>> list(range(0,5))

[0, 1, 2, 3, 4]

Treat it like a list and


it will behave like a list
250

Strictly speaking a range is not a list. But it is close enough to a list that
when you drop it into a for… loop, which is its most common use by far,
then it behaves like the list of numbers.

250
Why not just a list?

Most common use: for number in range(0, 10000):


Inefficient to make a
huge list just for this

“iterables” : anything that can be treated like a list

list(iterable) Explicit list

251

So why does the range() function not just produce a list?


Well, its most common use is in a for… loop. Only one value is required at a
time. If the list was explicitly created t would waste computer memory for all
the items not in use at the time and computer time for creating them all at
once.
(Truth be told, for the purposes of this course you wouldn’t notice.)

251
Ranges of numbers again
via list()

range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Start at 0
range(3, 10) [3, 4, 5, 6, 7, 8, 9]

range(3, 10, 2) [3, 5, 7, 9] Every nth number

range(10, 3, -2) [10, 8, 6, 4] Negative steps

252

The range() function can be used with different numbers of arguments.


A single argument gives a list running from zero to the number.
Two arguments gives the lists we have already seen.
A third argument acts as a “stride” and can be negative.

252
Indices of lists
>>> primes = [ 2, 3, 5, 7, 11, 13, 17, 19]

>>> len(primes)

>>> list(range(8))

[0, 1, 2, 3, 4, 5, 6, 7] valid indices

0 1 2 3 4 5 6 7

[2, 3, 5, 7, 11, 13, 17, 19] 253

Now that we have the range object we can move on to one of the most
important uses of it.
So far we have used a for… loop to step through the values in a list. From
time to time it is important to be able to step through the valid indices of the
list.
Observe that if we apply the range() function to a single number which is
the length of a list then we get a list of the valid indices for that list.

253
Direct value or via the index?
primes = [2, 3, 5, 7, 11, 13, 17, 19]

for prime in primes: Simpler


print(prime)

for index in range(len(primes)): Equivalent


print(primes[index])

254

What good is a list of valid indices?


There are two ways to step through the values in a list. One is directly; this
is the method we have met already. The second is to step through the
indices and to look up the corresponding value in the list.
These are equivalent and the first method we have already seen is shorter
to write. So why bother with the second?

254
Working with two lists: “dot product”

list1 = [ 0.3, 0.0, 0.4]

∙ × × ×
list2 = [ 0.2, 0.5, 0.6]

0.06 + 0.0 + 0.24 0.3

255

Consider operations on two lists.


A concrete example might be the “dot product” of two lists. This is the sum
of the products of matching elements.
So
[0.3, 0.0, 0.4] · [0.2, 0.5, 0.6]
= 0.3×0.2 + 0.0×0.5 + 0.4×0.6
= 0.06 + 0.0 + 0.24
= 0.6
How might we implement this in Python?

255
Working with two lists: indices

0 1 2
list1 = [0.3, 0.0, 0.4]
indices
list2 = [0.2, 0.5, 0.6]

sum = 0.0

for index in range(len(list1)) :

sum += list1[index]*list2[index]
Dealing with
print(sum)
values from
both lists at
the same time.256

We can approach this problem by running through the valid indices and
looking up the corresponding values from each list in the body of the for…
loop.

256
Iterables

range(from,to,stride)

Not a list but “close enough”

“Iterable”

257

The range object is one of the most commonly met examples of an iterable,
something that isn’t a list but is “close enough”.

257
A little more about iterables ― 1
>>> greek = ['alpha', 'beta', 'gamma', 'delta']

>>> greek_i = iter(greek)


iter
str 5 a l p h a
>>> next(greek_i) 4

'alpha' Offset 2 str 4 b e t a

>>> next(greek_i) str 5 g a m m a

'beta'
str 5 d e l t a
258

We will look a little more closely at iterables so that we can recognise them
when we meet them later.
If we start with a list then we can turn it into an iterable with the iter()
function.
An iterable ceated from a list is essentially the same as the list with a note of
how far through the list we have read. This reference starts at zero,
obviously.
Python provides a next() function which can act on any iterable which
returns the next value (or the first if we’ve not started) and increments this
internal counter.

258
A little more about iterables ― 2
iter
>>> next(greek_i) str 5 a l p h a
4
'gamma'
✗ str 4 b e t a

>>> next(greek_i)
str 5 g a m m a
'delta'

str 5 d e l t a
>>> next(greek_i)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
StopIteration ✗ 259

Note that next() complains vigorously if we try to run off the end. For this
course, where these errors are all fatal it means that we can’t use next()
directly. we don’t need to; we have the for… loop which handles the error
for us.

259
Progress
Non-lists as lists for letter in 'Hello':
...

range() range(limit)
range(start,limit)
range(start,limit,step)
range(3,7) [3,4,5,6]

“Iterables” greek_i = iter(greek)


next(greek_i)

Indices of lists for index in range(len(things)):

260
Parallel lists

260
Exercise 14

Complete exercise14.py

list1 = [ 0.3, 0.0, 0.4]


list2 = [ 0.2, 0.5, 0.6]
Subtract
0.1 -0.5 -0.2
Square
0.01 + 0.25 + 0.04 0.3
Add
5 minutes
261

This exercise develops the Python to calculate the square of the distance
between two 3D points. We could use our square root Python from earlier to
calculate the distance itself but we will meet the “real” square root function
later in this course so we’ll hold back from that for now.

261
List “slices”

>>> primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29] The list

>>> primes[3]
7 An item

>>> primes[3:9]
[7, 11, 13, 17, 19, 23] Part of the list
262

There is one last piece of list Pythonry we need to see.


Python has a syntax for making copies of parts of lists, which it calls “slices”.
If, instead of a simple index we put two indices separated by a colon then
we get the sub-list running from the first index up to but excluding the
seocnd index.

262
Slices ― 1
from
Up to but not
to
including…
primes[3:9]

3 9

primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]

primes[3:9] [7, 11, 13, 17, 19, 23]

Item 9 not 263


included

The last index is omitted as part of the “count from zero” thing.

263
Slices ― 2
primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]

primes[3:9] [7, 11, 13, 17, 19, 23]

primes[:9] [2, 3, 5, 7, 11, 13, 17, 19, 23]

primes[3:] [7, 11, 13, 17, 19, 23, 29, 31]

primes[:] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]


264

We can omit either or both of the numbers. Missing the first number means
“from the start” and missing the second means “right up to the end”.

264
Slices ― 3
primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]

primes[3:9] [7, 11, 13, 17, 19, 23]

primes[3:9:2] [7, 13, 19 ]

primes[3:9:3] [7, 17 ]

265

We can also add a second colon which is followed by a stride, just as with
range().

265
Copies and slices ― 1

>>> letters = ['a','b','c']

>>> alphabet = letters

list
str 1 a
letters 3

str 1 b
alphabet

str 1 c
266

Slices allow us to make copies of entire lists.


If we use simple name attachment then we just get two names for the same
list.

266
Copies and slices ― 2
>>> letters[0] = 'A'

>>> print(alphabet)

['A', 'b', 'c']

list
str 1 A
letters 3

str 1 b
alphabet

str 1 c
267

Changing an item in the list via one name shows up via the other name.

267
Copies and slices ― 3
>>> letters = ['a','b','c'] Slices are
copies.
>>> alphabet = letters[:]
letters alphabet

list list
str 1 a
3 3

str 1 b

str 1 c 268

Slices are copies, though, so if we attach a name to a slice from a list —


even if that slice is the entire list ― then we have two separate lists each
with their own name attached.

268
Copies and slices ― 4
>>> letters[0] = 'A' Slices are
copies.
>>> print(alphabet)
['a', 'b', 'c'] alphabet

letters
list list
str 1 A str 1 a
3 3

str 1 b

str 1 c 269

So changes in one don’t show in the other because they are not the same
list.

269
Progress

Slices

End-limit excluded

Slices are copies

items[from:to] items[from:to:stride]

items[:to] items[:to:stride]

items[from:] items[from::stride]

items[:] items[::stride] 270

270
Exercise 15

Predict what this Python will do.


Then run it. exercise15.py
Were you right?

foo = [4, 6, 2, 7, 3, 1, 9, 4, 2, 7, 4, 6, 0, 2]

bar = foo[3:12:3]

bar[2] += foo[4]

foo[0] = bar[1]

print(bar)
5 minutes
271

271
Files
Input Output

.txt

.dat

.csv

Reading Writing
272

Now we will look at something completely different that will turn out to be
just like a list: Files.
We want our Python scripts to be able to read in and write out files of text or
data.
We will consider reading files first and writing them second.

272
Reading a text file

File name 'treasure.txt' string

“opening” the file

File object book file

reading from the file

File contents 'TREASURE ISLAND' string

“closing” the file


273
Finished with the file

Reading from a file involves four operations bracketing three phases.


We start with a file name. This is a string of characters.
I want to be pedantic about something in this course: a file name is not a
file. A file is a lump of data in the computer’s long-term store. A file name is a
short piece of text.
We link a file name to a file by a process called “opening the file”. This takes
the file name and creates a Python file object which will act as our conduit to
the file proper.
We will use this file object to read data from the file into the Python script.
When we are done reading data out of the file (via the file object) we will
signal to both python and the operating system that we are done with it by
“closing” it. This disconnects us from the file and we would have to re-open
it if we wanted more data.

273
Opening a text file
Python function

File name

Read-only [text]
>>> book = open('treasure.txt', 'r') “mode”

Python file object

Read-only is
the default
book = open('treasure.txt' ) 274

We will start with opening a file.


We start with just the file name. This is passed into the open() function with
a second argument, 'r', indicating that we only want to read the file.
The function hooks into the operating system, which looks up the file by
name, checks that we have permission to read it, records the fact that we
are reading it, and hands us back a handle — the file object ― by which we
can access its contents.

274
Reading from a file object

“next line, please”

File object
>>> line1 = next(book)

First line of file

>>> line1 Includes the


“end of line”
'TREASURE ISLAND\n'
275

Now that we have this hook into the file itself, how do we read the data from
it?
File objects are iterators, so we can apply the next() function to them to get
the next line, starting with the first.

275
File object are iterable
>>> line2 = next(book)
Second line of file
>>> line2
'\n' A blank line

>>> line3 = next(book)

>>> line3 Third line of file


'PART ONE\n'
276

Note that a “blank” line actually contains the end of line character. It has
length 1, and is not an empty string, length 0.

276
Closing the file

Method built in to file object


>>> book.close()

Frees the file for other


programs to write to it.

277

When we are done reading the data we need to signal that we are done with
it. Python file objects have a close() method built into them which does
precisely this.

277
The file object ― 1

>>> book Text Input/Output

<_io.TextIOWrapper
name='treasure.txt' File name
encoding='UTF-8'>

Character encoding:
how to represent
letters as numbers.

278

UTF-8 means “UCS Transformation Format ― 8-bit”.


UCS means “”Universal Character Set. This is defined by International
Standard ISO/IEC 10646, Information technology — Universal multiple-octet
coded character set (UCS). For more information than you could possibly
want on this topic visit the Unicode web pages: www.unicode.org.

278
The file object ― 2
File name

Text encoding

file 29 treasure.txt UTF-8

TREASURE ISLAND↵
“offset”: how far into ↵
the file we have read PART ONE↵

☞ ↵
The Old Buccaneer↵

Pointer to the file
on the file system

279

The Python file object contains a lot of different bits of information. There
are also lots of different sorts of file object, but we are glossing over that in
this introductory course.
What they share is a reference into the operating system’s file system that
identifies the specific file and acts as the declaration to the operating system
that the Python process is using the file.
They also share an “offset”. This is a number that identifies how far into the
file the program has read so far. The next() function reads from the offset
to the next new line and increases the offset to be the distance into the file
of the new line character.
The file object also records the name it was opened from and the text
encoding it is using to convert bytes in the file to characters in the program.

279
Reading through a file
Treat it like a list and
it will behave like a list

list(file_object) List of lines in the file

>>> book = open('treasure.txt', 'r')

>>> lines = list(book)

>>> print(lines)
280

Given that a file is an iterable, we can smply convert it into a list and we get
the list of lines.

280
Reading a file moves the offset
>>> book = open('treasure.txt', 'r')
!
>>> lines_a = list(book)

>>> print(lines_a)

… Huge output

>>> lines_b = list(book)

>>> print(lines_b)

[] Empty list 281

Note, however, that the act of reading the file to get the lines reads through
the file, so doing it twice gives an empty result second time round.

281
Reading a file moves the offset
>>> book = open('treasure.txt', 'r')
File object starts with offset at start.
>>> lines_a = list(book)
Operation reads entire file from offset.
>>> print(lines_a)
Offset changed to end of file.

>>> lines_b = list(book)


Operation reads entire file from offset.
>>> print(lines_b)
So there's nothing left to read.
[] 282

recall that the reading starts at the offset and reads forwards — to the end of
the file in this example. It also moves the offset to what was last read. So
the offset is changed to refer to the end of the file.

282
Resetting the offset
>>> book = open('treasure.txt', 'r')

>>> lines_a = list(book)

>>> print(lines_a)

>>> book.seek(0) Set the offset explicitly

>>> lines_b = list(book)

>>> print(lines_b) 283

We can deliberately change the offset. For text files with lines of different
lengths this can be more complex that you would imagine. The only safe
value to change the offset to is zero which takes us back to the start of the
file.

283
Older file object methods
>>> book = open('treasure.txt', 'r')

>>> book.readline()

'TREASURE ISLAND\n'

>>> book.readlines()

['\n', 'PART ONE\n' … ]

284

There are other ways to read in the data. Earlier versions of Python only
supported a couple of built-in methods. You may still see these in other
people’s scripts but we don’ recommend writing them in scripts that you
create.

284
Typical way to process a file
book = open('treasure.txt', 'r')

for line in book : Treat it like a list…


285

Being able to read a single line of a file is all very well. Converting an entire
book into a list of its lines might prove to be unwieldy.
What is the typical way to do it?
Given that files can be treated like lists the easiest way to process each line
of a file is with a for… loop.

285
Example: lines in a file
book = open('treasure.txt', 'r')

n_lines = 0 Line count

for line in book : Read each line of the file

n_lines += 1 Increment the count

print(n_lines) Print out the count

286
book.close()

For example, we could just increment a counter for each line to count the
number of lines.

286
Example: characters in a file
book = open('treasure.txt', 'r')

n_chars = 0

for line in book : Number of characters on the line

n_chars += len(line)

Increase the count by that many


print(n_chars)

287
book.close()

We could measure the length of the line and increment the counter by the
number of characters in the line to count the total number of characters in
the file.

287
Progress

Reading files

Opening file book = open(filename, 'r')

Reading file for line in book:


...

Closing file book.close()

File offset book.seek(0)


288

288
Exercise 16

Complete a script to count exercise16.py


lines, words and characters
of a file.

5 minutes
289

Count words & lines.

289
Writing files

File name 'treasure.txt' string

“opening” the file

Data to write 'TREASURE ISLAND' string

writing to the file

File object book file

“closing” the file


290
Finished with the file

Enough of reading files Robert Louis Stephenson has prepared for us. Let’s
write our own.
This is again a three phase process. We will open a file for writing, write to it
and then close it.

290
Opening a text file for writing

Open for
writing [text]

>>> output = open('output.txt' , 'w')

This will truncate


an existing file
! 291

Opening a file for writing is the same as opening it for reading except that
the mode is 'w' for writing.
If the file already exists then this overwrites it. The file gets truncated to zero
bytes long because you haven’t written to it yet.

291
Writing to a file object ― 1

File object

Method built in
to file object
>>> output.write(line1)

Data being written

292

A writeable file object has a method write() which takes a text string
(typically but not necessarily a line) and writes it to the file.

292
Writing to a file object ― 2

>>> output.write('alpha\n') Typical use: whole line.

Includes “end of line”

>>> output.write('be')
Doesn’t have
to be whole lines
>>> output.write('ta\n')

>>> output.write('gamma\ndelta\n')

Can be multiple lines 293

How the data is chopped up between writes is up to you.

293
Closing the file object

>>> output.close() Vital for written files

294

It also has a close() method.

294
Importance of closing
!
Data “flushed” to disc on closure.

write “flush”

Python script File object File system 295

Closing files is even more important for written files that read ones.
It is only when a file is closed that the data you have written to the Python
file object is definitely sent to the operating system’s file. This is a process
called “flushing the file to disc”.
Writing to disc is slow by computing standards so, for efficiency reasons,
systems like Python tend to wait until they have at least a certain amount of
data for a file before they flush it to disc. If your program exists before
flushing then the data may be lost. Closing a file signals that there will be no
more data coming for it so Python flushes whatever it has in hand to the disc
as part of the closure process.

295
Importance of closing promptly !
Files locked for other access

open ['w']
✗ open ['r']

296
(More a problem for Windows than Unix)

There’s more to it than just flushing, though. Holding a file open signals to
the underlying computer operating system that you have an interest in the
file. How the operating system reacts to this varies from system to system,
but Microsoft Windows™ will lock a file so that if you have it open for writing
nobody else can open it for reading, even if you don’t plan to write any more
to it than you have already.

296
Progress

Writing files

Opening files for writing book = open(filename, 'w')

Writing data book.write(data)

Closing file important book.close()

Flushing book.flush()
297

297
Exercise 17

5 minutes
298

298
Functions

y = f(x)

299

299
Functions we have met
input(prompt) bool(thing)

len(thing) float(thing)

open(filename, mode) int(thing)

print(line) list(thing)

range(from, to, stride) str(thing)


Not that many!
type(thing)
“The Python Way”:
ord(char)
If it is appropriate to
an object, make it a 300
chr(number) method of that object.

This is the complete set of Python functions that we have met to date.
Actually it’s surprising how few there are, not how many. Python’s
philosophy leads to functions that only make sense for a particular sort of
object being methods of that object, not free-standing functions.
We are now going to write our own functions.

300
Why write our own functions?
Easier to …
… read

… write

… test

… fix

… improve

… add to
“Structured
programming”
… develop
301

Why?
Moving our scripts’ functionality into functions and then calling those
functions is going to make everything better. This is the first step towards
“structured programming” which is where programming goes when your
scripts get too long to write in one go without really thinking about it.

301
Defining a function

(y1, y2, y3) = f(x1, x2, x3, x4, x5)

Identify the inputs

Identify the processing

Identify the outputs

302

So what do we need to do?


Well any functions starts by defining what inputs it needs, what it does with
those inputs to generate the results and exactly what results/outputs it
generates.

302
A function to define: total()

Sum a list

[1, 2, 3] 6

[7, -4, 1, 6, 0] 10

[] 0 “Edge case”

303

To give ourselves a simple but concrete example to keep in mind we will set
ourselves the challenge of writing a function that sums the elements of a list.
This may sound trivial but immediately raises some interesting cases that
need to be considered.
What is the sum of an empty list? Zero? Is that an integer zero or a floating
point zero? (Or a complex zero?)
We will say it should sum to an integer zero.

303
Defining a Python function ― 1
define a function called …
name of function
inputs
def total( … ): colon

304

We will plunge straight into the Python.


The Python keyword to define a function is “def”.
This is followed by the name of the function, “total” in this case.
This is followed by a pair of round brackets which will contain all the input
values for the function.
Finally there is a colon to mark the end of the line and the beginning of the
body of the function.

304
Defining a Python function ― 2

name for the input


def total(numbers):
This name is
internal to
the function.

305

Our function takes a single input: the list of numbers to be summed.


What goes inside the brackets on the def line is the name that this list will
have inside the function’s definition. This is the “x” in maths. This internal
names is typically unrelated to the name the list has in the main body of the
script.
It is always a good idea to name your inputs (and other variables)
meaningfully. Please try to avoid calling them “x”, “y”, or “z”.
We will call ours “numbers”.

305
Defining a Python function ― 3

def total(numbers): Colon followed by indentation

306

As ever with Python a colon at the end of a line is followed by an indented


block of code. This will be the body of the function where we write the
Python that defines what the function actually does with the input(s) it is
given.

306
Defining a Python function ― 4

def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number “Body” of function

307

For our function this is particularly simple.

307
Defining a Python function ― 4

def total(numbers):
These variables exist only
sum_so_far = 0
within the function’s body.
for number in numbers:
sum_so_far += number

308

The numbers name we specified on the def line is visible to Python only
within the function definition. Similarly any names that get created within the
function body exist only within that function body and will not be visible
outside. Nor will they clash with any other uses of those names outside the
function body.
In our example code the name “numbers” is defined in the def line, the
“sum_so_far” name is defined explicitly in the function body and the
“number” name is defined by the for… loop as its loop variable.
None of these interact with the Python outside the function definition.

308
Defining a Python function ― 5

def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number

return sum_so_far This value


is returned

return this value 309

Finally we need to specify exactly what value the function is going to return.
We do this with another Python keyword, “return”. The value that follows
the return keyword is the value returned by the function.
When Python reaches the return statement in a function definition it hands
back the value and ends the execution of the function body itself.

309
Defining a Python function ― 6

And that’s it!


def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number

return sum_so_far

Unindented
after this 310

And that’s all that is involved in the creation of a Python function.

310
Defining a Python function ― 7

And that’s it!

All internal names internal No need to avoid reusing names

All internal names cleaned up No need for del

311

Note that because of this isolation of names we don’t have to worry about
not using names that are used elsewhere in the script.
Also, as part of this isolation all these function-internal names are
automatically cleared when the function finishes. We do not need to worry
about deleting them.

311
Using a Python function ― 1
def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number

return sum_so_far

print(total([1, 2, 3]))

The list we
want to add up
312

We use this function we have defined in exactly the same way as we would
use a function provided by Python.

312
Using a Python function ― 2
def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number

return sum_so_far

print(total([1, 2, 3]))

The function we
have just written

313

313
Using a Python function ― 3
def total(numbers):

sum_so_far = 0

for number in numbers:


sum_so_far += number

return sum_so_far

print(total([1, 2, 3]))

Printing out
the answer

314

314
Using a Python function ― 4
def total(numbers):
nb: Unix prompt
sum_so_far = 0
$ python3 total1.py
for number in numbers:
sum_so_far += number 6

return sum_so_far

print(total([1, 2, 3]))

total1.py
315

The file total1.py in your home directories contains exactly the code you see
here.

315
Using a Python function ― 5
def total(numbers):

sum_so_far = 0
$ python3 total2.py
for number in numbers:
sum_so_far += number 6
10
return sum_so_far 0

print(total([1, 2, 3]))
print(total([7,-4,1,6,0])) Use the function
multiple times
print(total([]))

total2.py
316

316
Progress

Functions

“Structured programming”

Defining a function def function(input):


...

Returning a value return output

317

317
Exercise 18

5 minutes
318

318
Reminder about indices
def total(numbers):
sum_so_far = 0
for number in numbers:
sum_so_far += number total2.py
return sum_so_far

Equivalent

def total(numbers):
sum_so_far = 0
for index in range(len(numbers)):
sum_so_far += numbers[index] total3.py
return sum_so_far
319

Let’s quickly remind ourselves about how we can uses indices for lists rather
than values from lists directly.
We found this particularly useful when we were traversing more than one list
at once.

319
Example of multiple inputs
Want a function to add two lists of the same length term-by-term:

[1, 2, 3] & [5, 7, 4] [6, 9, 7]

[10, -5] & [15, 14] [25, 9]

[3, 7, 4, 1, 7] & [8, 4, -6, 1, 0] [11, 11, -2, 2, 7]

Two inputs
320

So how do we build functions that take in more than one input at once?

320
Functions with multiple inputs
Multiple inputs are
separated by commas
def add_lists(a_list, b_list):

sum_list = []

for index in range(len(a_list)):

sum = a_list[index] + b_list[index]

sum_list.append(sum)

return sum_list
321

The Python syntax for multiple inputs is much the same as it is for a
mathemtical function: we separate the inputs by commas.

321
Functions with multiple inputs
We have
two lists…
def add_lists(a_list, b_list):

sum_list = [] …so we have


to use indexing
for index in range(len(a_list)):

sum = a_list[index] + b_list[index]

sum_list.append(sum)

return sum_list
322

Note that functions that take in more than one list typically need to use
indices.

322
Multiple outputs
Write a function to find minimum and maximum value in a list

[1, 2, 3] 1 & 3

[10, -5] -5 & 10

[3, 7, 4, 1, 7] 1 & 7

Two outputs
323

But what if we want to return multiple values?


We can write a function that determines the minimum value in a list, and we
can write a function that returns the maximum. What do we do if we want to
find both?

323
Finding just the minimum
def min_list(a_list): minlist.py

min_so_far = a_list[0] List cannot be empty!

for a in a_list :

if a < min_so_far:
min_so_far = a

return min_so_far Returning a single value

324

So here’s the function that determines the minimum value in a list…

324
Finding just the maximum
def max_list(a_list): maxlist.py

max_so_far = a_list[0]

for a in a_list :

if a > max_so_far: Only real change


max_so_far = a

return max_so_far Returning a single value

325

…and just the maximum.

325
Finding both
def minmax_list(a_list):

min_so_far = a_list[0]
max_so_far = a_list[0]

for a in a_list :

if a < min_so_far:
min_so_far = a

if a > max_so_far:
max_so_far = a

326
return what? This is the real question

Combining the bodies of these two functions is quite straightforward.


But what do we return?

326
Returning both
def minmax_list(a_list): minmaxlist.py

min_so_far = a_list[0]
max_so_far = a_list[0]

for a in a_list :

if a < min_so_far:
min_so_far = a

if a > max_so_far:
max_so_far = a

327
return min_so_far, max_so_far A pair of values

Two return two values we simply put them both after the return statement
separated by a comma, just as we would have done with the inputs.

327
“Tuples”

e.g. min_value, max_value Pair

min_value, avg_value, max_value Triple

Commas

Often written with parentheses:

(min_value, max_value)

(min_value, avg_value, max_value)

328

These sets of values separated by commas (but not in square brackets to


make a list) are called “tuples” in Python. Sometimes they are written with
round brackets around them to make it clearer that they come together. But
it’s the comma that is the active ingredient making them a tuple, not the
brackets.

328
Using tuples to return values
def … In the function definition

return (min_value, max_value)

Using the function

(minimum, maximum) = minmax_list(values)

329

If we return a pair of values in a tuple, we can also attach a pair of names to


them as a tuple too.

329
Using tuples to attach names

alpha = 12
(alpha , beta) = ( 12, 56 )
beta = 56

330

We can do this outside the context of functions returning values, of course.


We can do it anywhere.

330
Swapping values

>>> alpha = 12

>>> beta = 56

>>> (alpha, beta) = (beta, alpha) Swapping values

>>> print(alpha)

56

>>> print(beta)

12 331

Because the entire right hand side is evaluated before the left hand side is
considered this lets us use tuples for some particularly useful tricks. perhaps
the most useful is swapping two values.

331
Assignment works right to left

alpha = 12

beta = 56

(alpha, beta) = (beta, alpha)

Stage 1: (beta, alpha) (56, 12)

Stage 2: (alpha, beta) = (56, 12)

332

The values associated with the names are evaluated first. Then the names
get reattached to those values, regardless of what names they might have
had before.

332
Recall this “gotcha”:
!
a = 10

b = 7

a = a + b a = 17 a has now changed!

b = a - b b = a - b b ≠ 10 - 7 = 3
= 17 - 7
= 10

333

We can also use it to help us with our “change of coordinates” example.

333
Again: assignment works right to left

a = 10

b = 7

(a, b) = (a + b, a - b)

Stage 1: (a+b, a-b) (10+7, 10-7) (17, 3)

Stage 2: (a, b) = (17, 3)

334

This works in exactly the same way.

334
Progress

Multiple inputs def thing(in1, in2, in3):

Multiple outputs return (out1, out2, out3)

“Tuples” (a, b, c)

Simultaneous assignment (a, b) = (a+b, a-b)

335

335
Exercise 19

Take the script from exercise 16 and turn it into:

1. the definition of a function file_stats() that takes a file


name and returns a triple (n_lines, n_words, n_chars)

2. a call to that function for file name treasure.txt

3. a print of that triple.

5 minutes
336

336
One object or many?

two objects

“a pair of objects”
one object

337

Tuples tend to blur the boundary between multiple objects and a single
object.

337
Tuples as single objects ― 1
>>> x = 20
>>> type(x)
<class 'int'>

>>> y = 3.14
>>> type(y)
<class 'float'>

>>> z = (20, 3.14) One name → Pair of values


>>> type(z)
<class 'tuple'> A single object 338

We can treat a tuple as a single object. It has a type called , “tuple”


unsurprisingly.

338
Tuples as single objects ― 2

>>> z = (20, 3.14)

>>> print(z)

(20, 3.14)

>>> w = z Single name → Single tuple

>>> print(w)

(20, 3.14)

339

We can manipulate the tuple as a single object quite happily.

339
Splitting up a tuple

>>> print(z)

(20, 3.14)

>>> (a,b) = z Two names → Single tuple

>>> print(a)

20

>>> print(b)

3.14
340

But a tuple is fundamentally made of separable pieces and can be split up.

340
How tuples are like lists

>>> z = (20, 3.14)

>>> z[1] Indices

3.14

>>> len(z) Length

>>> z + (10, 2.17) Concatenation

(20, 3.14, 10, 2.17)


341

Tuples are a lot like lists at first glance.

341
How tuples are not like lists

>>> z = (20, 3.14)

>>> z[0] = 10

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not
support item assignment “Immutable”

342

They have one critical difference, though. A tuple is “immutable”. You cannot
change individual elements in a tuple. You get the whole tuple and you can’t
fiddle with it.

342
Progress

Tuples as single objects thing = (a, b, c)

Splitting up a tuple (x, y, z) = thing

Tuples as lists thing[0]


len(thing)
thing + thing

Immutability thing[0] = 10 ✗
343

343
Functions we have written so far

total(list)

squares(N)

add_lists(list1,list2)

minmax_list(list)

344

To date we have written a small number of functions ourselves.


Once we become serious Python programmers using the computer for our
day job then we would expect to write many more.

344
Reusing functions within a script
def square(limit):
... One definition

...

squares_a = square(34)

...

five_squares = squares(5) Multiple uses in


the same file
...

squares_b = squares(56)

...

Easy! 345

Within a script reusing a function is easy. We simply call the function


whenever we want it.

345
Reusing functions between scripts?
def squares(limit):
... One definition

...
squares_a = squares(34)
Multiple uses in
...
... multiple files
five_squares = squares(5)
... ...
squares_b = squares(56)
...

How? 346

But what happens if we want to use a function in more than one script?

346
“Modules”

def square(limit): ...


...
five = squares(5)

def cubes(limit): ...


...

Definition Use

Module: a container of functions


347

Python has a mechanism to assist with this called “modules”. A module is a


collection of functions (and other material) which can then be imported into a
script and used within that script. If we can write our own module with our
own functions then we can import them into our own scripts.

347
Modules: a worked example ― 1a
def squares(limit):
answer = []
utils.py for n in range(0,limit):
answer.append(n**2)
return answer

def total(numbers):
Starts empty sum_so_far = 0
for number in numbers:
sum_so_far += number
return sum_so_far

text = input('Number? ')


number = int(text)
squares_n = squares(number)
total_n = total(squares_n)
print(total_n)
348
sum_squares.py

We will start with a file called sum_squares.py which uses two functions
to add up the squares of numbers from zero to some limit. We want to
transfer those function definitions into a different file which we will call
utils.py (which starts empty) but still be able to use them in our original
file.

348
Modules: a worked example ― 1b

$ python3 sum_squares.py

Number? 5

30 = 0 + 1 + 4 + 9 + 16

$ python3 sum_squares.py

Number? 7

91 = 0 + 1 + 4 + 9 + 16 + 25 + 36

349

Just to prove I’m not fibbing, here it is working before we move anything
about.

349
Modules: a worked example ― 2a
def squares(limit):
answer = []
for n in range(0,limit):
answer.append(n**2) text = input('Number? ')
return answer number = int(text)
squares_n = squares(number)
def total(numbers): total_n = total(squares_n)
sum_so_far = 0 print(total_n)
for number in numbers:
sum_so_far += number
return sum_so_far
sum_squares.py

utils.py
Move the definitions
into the other file.
350

Using the text editor we move the definitions from sum_squares.py to


utils.py.

350
Modules: a worked example ― 2b

$ python3 sum_squares.py

Number? 5

Traceback (most recent call last):


File "sum_squares.py", line 4, in <module>
squares_n = squares(number)
NameError: name 'squares' is not defined

Because we have (re)moved its definition.

351

Unsurprisingly, this breaks sum_squares.py.

351
Modules: a worked example ― 3a
def squares(limit): import utils
answer = []
for n in range(0,limit):
answer.append(n**2) text = input('Number? ')
return answer number = int(text)
squares_n = squares(number)
def total(numbers): total_n = total(squares_n)
sum_so_far = 0 print(total_n)
for number in numbers:
sum_so_far += number
return sum_so_far
sum_squares.py

utils.py
import: Make
import utils a reference to
and not the other file.
352
import utils.py

We need to import the functioned defined in utils.py into


sum_squares.py.
First, we add the instruction “import utils” to the top of the
stm_squares.py file.
Note that we import “utils”, not “utils.py”.

352
Modules: a worked example ― 3b

$ python3 sum_squares.py

Number? 5

Traceback (most recent call last):


File "sum_squares.py", line 4, in <module>
squares_n = squares(number)
NameError: name 'squares' is not defined

Still can’t find the function(s).

353

On its own this is not sufficient.

353
Modules: a worked example ― 4a
import utils

squares() text = input('Number? ')


utils.squares() number = int(text)
squares_n = utils.squares(number)
total_n = utils.total(squares_n)
total() print(total_n)

utils.total()
sum_squares.py

utils.…: Identify
the functions
as coming from
354
the module.

We have to indicate to Python that these functions it is looking for in


sum_squares.py come from the utils module. To do this we include
“utils.” at the start of their names.

354
Modules: a worked example ― 4b

$ python3 sum_squares.py

Number? 5

30

$ python3 sum_squares.py

Number? 7

91
Working again!

355

And now it works.

355
Progress

Sharing functions between scripts

“Modules”

Importing modules import module

Using functions from modules module.function()

356

356
Exercise 20

Move the function file_stats() from exercise18.py


into utils.py and edit exercise18.py so that it still works.

5 minutes
357

357
The Python philosophy
A small core … plus lots
language … of modules

math
sys
“Batteries
included”
string 358

We have met the majority of the Python language already! But obviously
Python has facilities to do much more than we have seen so far. The trick is
that Python comes with a large number of modules of its own which have
functions for performing no end of useful things.
This philosophy is called “batteries included”. You probably already have the
module you need to do your specialist application.

358
Example: the “math” module

>>> import math Load in the “math” module.

Run the sqrt() function…


>>> math.sqrt(2.0)
… from the math module.
1.4142135623730951

359

Let’s see an example of an “included battery”. At the very start of this course
we write ourselves a square root program. Now let’s see what Python offers
as an alternative.
We import the “math” module. (No trailing “s”; this is the American spelling.)
In the math module is a sqrt() function. We can access this as
math.sqrt().
Most of the fundamental mathematical operations can be found in the math
moWe will see how to find out exactly what is in a module in a few slides’
time.

359
import module as alias

>>> import math


Too long to keep typing?
>>> math.sqrt(2.0)

1.4142135623730951

>>> import math as m “Alias”

>>> m.sqrt(2.0)

1.4142135623730951 360

There are those who object to typing. If “math” is too long then we can use
an aliasing trick to give the module a shorter name.
(The problem is rarely with math. There is a built-in module called
“multiprocessing” though which might get tiresome.)

360
Don’t do these

>>> from math import sqrt


Much better
>>> sqrt(2.0) to track the
module. !
1.4142135623730951

>>> from math import *

>>> sqrt(2.0)
!!
1.4142135623730951
361

python does permit you to do slightly more than that. You can suppress the
name of the module altogether.
You are beginners so please take it from an old hand on trust that this turns
out to be a very bad idea. You want to keep track of where your functions
came from!

361
What system modules are there?
Python 3.2.3 comes with over 250 modules.

glob math argparse csv

io cmath datetime html

os random getpass json

signal colorsys logging re

subprocess email pickle string

sys http sqlite3 unicodedata

tempfile webbrowser unittest xml 362

There are many modules that come with Python.

362
“Batteries included”

>>> help('modules')

Please wait a moment while I gather a list


of all available modules...

CDROM binascii inspect shlex


263 modules
bdb importlib shelve

Enter any module name to get more help. Or,


type "modules spam" to search for modules whose
descriptions contain the word "spam".
363
Not quite this simple

To find out exactly what modules come with your version of Python ask the
help system.
A word of warning, though. The text at the bottom “Enter any module
name…” is not quite right.
If you give the help() command with no argument then you are dropped
into an interactive help system. There you can type the name of a module or
type “modules spam”, etc.

>>> help()

Welcome to Python 3.1! This is the online help utility.



help> modules subprocess

Here is a list of matching modules. Enter any module


name to get more help.

subprocess - subprocess - Subprocesses with accessible


I/O streams

help> quit

>>>

363
Additional downloadable modules
Numerical Databases

numpy pyodbc

scipy psycopg2 PostgreSQL

MySQLdb MySQL

cx_oracle Oracle

Graphics ibm_db DB2

matplotlib pymssql SQL Server

364

But, of course, there’s never the particular module you want. There are
modules provided by people who want Python to interoperate with whatever
it is they are offering.
There are three sets of additional modules that you may end up needing to
know about.
The numerical and scientific world has a collection of modules called
Numerical Python (“numpy”) and “scientific python” (”scipy”) which contain
enormous amounts of useful functions and types for numerical processing.
Every database under the sun offers a module to let Python access it.
Finally there is a module to offer very powerful 2D graphics for data
visualisation and presentation.

364
An example system module: sys
import sys $ python3 argv.py one two three

print(sys.argv)
['argv.py', 'one', 'two', 'three']

index 0 1 2 3
argv.py

$ python3 argv.py 1 2 3

['argv.py', '1', '2', '3']

Always strings
365

We will take a brief look at another commonly used module to illustrate


some of the things Python has hidden away in its standard set.
The “sys” module contains many systems-y things. For example, it contains
a list called sys.argv which contains the argument values passed on the
command line when the script was launched.
Note two things:
1. that item zero in this list is always the name of the script itself,
2. the items are always strings

365
sys.exit()

exit() What we have been using

sys.exit(rc) What we should use

“Return Code”: an integer

0: Everything was OK

≠0: Something went wrong


366

Also tucked away in the sys module is the sys.exit() function.


Up to this point we have been using the exit() function to quit our scripts
early. However this function is something of a filthy hack and sys.exit()
provides superior quitting and an extra facility we will be able to make use
of.
The sys.exit() function takes an integer argument. This is the program’s
“return code” which is a very short message back to the operating system to
indicate whether the program completed successfully or not. A return code
of 0 means “success”. A non-zero return code means failure. Some
programs use different non-zero codes for different failures but many
(most?) simply use a value of 1 to mean “something went wrong”.
If your script simply stops because it reached the end then Python does an
automatic sys.exit(0).

366
An example system module: sys
But also…

sys.modules All modules currently imported

sys.path Directories Python searches for modules

sys.version Version of Python

sys.stdin Where input inputs from

sys.stdout Where print prints to

sys.stderr Where errors print to

sys.float_info All the floating point limits


367

…and there’s more!

And there’s plenty more…

367
Modules in Python

“How do I do
X in Python?”

“What’s the Python


module to do X?”

“Where do I find
Python modules?”
368

So the Python philosophy places a lot of functionality into its modules.


This means that we have to be able to find modules and know what they
can do.

368
Finding modules

Python: Built-in modules

SciPy: Scientific Python modules

PyPI: Python Package Index

Search: “Python3 module for X”


369

Some useful URLs:

http://docs.python.org/py3k/py-modindex.html
This contains the list of all the “batteries included” modules that come with
Python. For each module it links through to their documentation.

http://www.scipy.org/Topical_Software
http://numpy.scipy.org/
Scientific Python contains very many subject-specific modules for Python.
Most depend on the Numerical Python module numpy.

http://pypi.python.org/pypi (do check for Python3 packages)


This is the semi-official dumping ground for everything else.

http://www.google.co.uk/
And for everything else there’s Google (who are big Python users, by the
way).

369
Help with modules

>>> import math

>>> help(math)

NAME
math

DESCRIPTION
This module is always available. It provides
access to the mathematical functions defined
by the C standard.

… 370

I promised information on how to find out what is in a module. Here it is.


Once a module has been imported you can ask it for help.

370
Help with module functions

FUNCTIONS

acos(x)
Return the arc cosine (measured in
radians) of x.

>>> math.acos(1.0)

0.0

371

The help will always include information on every function in the module…

371
Help with module constants

DATA
e = 2.718281828459045
pi = 3.141592653589793

>>> math.pi

3.141592653589793

372

…and every data item.

372
Help for our own modules?
def squares(limit): >>> import utils
answer = []
for n in range(0,limit):
answer.append(n**2)
>>> help(utils)
return answer
NAME
def total(numbers): utils
sum_so_far = 0
for number in numbers:
sum_so_far += number FUNCTIONS
return sum_so_far squares(limit)

total(numbers)
utils.py
Basic help already FILE
provided by Python /home/y550/utils.py
373

What help can we get from our own module?


By now you should have a utils.py file with some functions of your own
in it. The help simply lists the functions the module contains and the file it is
defined in.

373
Adding extra help text
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils)

def squares(limit): NAME


answer = [] utils
for n in range(0,limit):
answer.append(n**2)
return answer DESCRIPTION
Some utility functions
def total(numbers): from the Python for
sum_so_far = 0 Absolute Beginners course
for number in numbers:
sum_so_far += number
return sum_so_far FUNCTIONS
squares(limit)
374

utils.py total(numbers)

But we can do better than that.


If we simply put a Python string (typically in long text triple quotes) at the top
of the file before any used Python (but after comments is fine) then this
becomes the description text in the help.
Note: You need to restart Python and re-import the module to see changes.

374
Adding extra help text to functions
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils)

def squares(limit): NAME


"""Returns a list of utils
squares from zero to
limit**2.
""" DESCRIPTION
answer = [] ...
for n in range(0,limit):
answer.append(n**2) FUNCTIONS
return answer squares(limit)
Returns a list of
squares from zero to
limit**2. 375

utils.py

If we put text immediately after a def line and before the body of the
function it becomes the help text for that function, both in the module-as-a-
whole help text…

375
Adding extra help text to functions
"""Some utility functions >>> import utils Fresh start
from the Python for
Absolute Beginners course
"""
>>> help(utils.squares)

def squares(limit): squares(limit)


"""Returns a list of Returns a list of
squares from zero to squares from zero to
limit**2.
limit**2.
"""
answer = []
for n in range(0,limit):
answer.append(n**2)
return answer

376

utils.py

…and in the function-specific help text.

376
Progress
Python a small language… Functionality Module

…with many, many modules

System modules

Foreign modules

Modules provide help help(module)

Doc strings help(module.function)


377

377
Exercise 21
Add help text to your utils.py file.

5 minutes
378

378
Recap: Lists & Indices

greek = ['alpha', 'beta', 'gamma']

list
str 5 a l p h a greek[0]
3

Position 0 str 4 b e t a greek[1]


Position 1
Position 2 str 5 g a m m a greek[2]

379

We have one last Python type to learn about. To give it some context, we
will recap the list type that we have spent so much time using.
A list is basically an ordered sequence of values. The position in that
sequence is known as the index.

379
“Index in ― Value out”

index list value


Must be
a number

1 greek[1] 'beta'
380

If we now forget about the internals of a list, though, we can think of it as


“some sort of Python object” that takes in a number (the index) and spits out
a value.

380
Other “indices”: Strings?

English dictionary Spanish

'cat' 'gato'

'dog' dictionary 'perro'

'mouse' 'ratón'
381

Can we generalise on this idea by moving away from the input (the index)
needing to be a number?
Can we model a dictionary where we take in a string (a word in English, say)
and give out a different string (the corresponding word in Spanish, say).
(Note: the author is fully aware that translation is not as simple as this. This
is just a toy example.)

381
Other “indices”: Tuples?

(x, y) dictionary Objects

(2,5) 'Treasure'
dictionary
(4,5) 'Fortress'

382

Or, perhaps, pairs of numbers (x,y) in and items on a map out?

382
Python “dictionaries”

>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }

>>> en_to_es['cat']

'gato'

383

Python does have exactly such a general purpose mapper which it calls a
“dict”, short for “dictionary”.
Here is the Python for establishing a (very small) English to Spanish
dictionary that knows about two words.
We also see the Python for looking up a word in the dictionary.
We will review this syntax in some detail…

383
Creating a dictionary — 1

Curly brackets
Comma

{ 'cat':'gato' , 'dog':'perro' }

'cat' → 'gato' 'dog' → 'perro'

384

First we will look at creating a dictionary. In the same way that we can
create a list with square brackets, we can create a dictionary with curly
ones.
Each item in a dictionary is a pair of values separated by a colo
They are separated by commas.n.

384
Creating a dictionary — 2

'cat' : 'gato'

{ 'cat':'gato' , 'dog':'perro' }

“key” : “value”

385

The pairs of items separated by colons are known as the “key” and “value”.
The key is what you put in (the English word in this example) that you look
up in the dictionary and the value is what you get out (the translation into
Spanish in this example).

385
Using a dictionary — 1

>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }

Creating the dictionary

>>> en_to_es['cat'] Using the dictionary

'gato'

386

Now we have seen how to create a (small) dictionary we should look at how
to use it.

386
Using a dictionary — 2

Square brackets

en_to_es[ 'cat' ] 'gato'

dictionary key value

387

To look something up in a dictionary we pass it to the dictionary in exactly


the same way as we passed the index to a list: in square brackets. Curly
brackets are just for creating a dictionary; after that it’ square brackets
again.

387
Missing keys

>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }

>>> en_to_es['dog']

'perro' ✓
>>> en_to_es['mouse']

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'mouse' Error message
388

The equivalent to shooting off the end of a list is asking for a key that’s not
in a dictionary.

388
Dictionaries are one-way
!
>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }

>>> en_to_es['dog']

'perro' ✓
>>> en_to_es['perro']

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'perro'
389
Looking for a key

Also note that dictionaries are one-way.

389
Adding to a dictionary

>>> en_to_es = { 'cat':'gato' , 'dog':'perro' }

Initial dictionary has no 'mouse'

>>> en_to_es['mouse'] = 'ratón'

Adding 'mouse' to the dictionary

>>> en_to_es['mouse']

'ratón'

390

Adding key-value pairs to a dictionary is a lot easier than it is with lists. With
lists we needed to append on the end of a list. With dictionaries, because
there is no inherent order, we can simply define them with a simple
expression on the left hand side.

390
Removing from a dictionary

>>> print(en_to_es)

{'mouse': 'ratón', 'dog': 'perro', 'cat': 'gato'}

>>> del en_to_es['dog']

>>> print(en_to_es)

{'mouse': 'ratón', 'cat': 'gato'}

391

We can use del to remove from a dictionary just as we did with lists.

391
Progress

Dictionaries Key Value

{ key1:value1 , key2:value2, key3:value3 }

Looking up values dictionary[key] value

Setting values dictionary[key] = value

Removing keys del dictionary[key]


392

392
Exercise 22

Complete exercise22.py to create


an English to French dictionary.

cat chat

dog chien

mouse souris

snake serpent
5 minutes
393

393
What’s in a dictionary? ― 1
>>> en_to_es
{'mouse': 'ratón', 'dog': 'perror', 'cat': 'gato'}

>>> en_to_es.keys()
dict_keys(['mouse', 'dog', 'cat'])

Orders
match
>>> en_to_es.values()
dict_values(['ratón', 'perro', 'gato'])

Just treat them like lists (or convert them to lists) 394

To date we have created our own dictionaries. If we are handed one how do
we find out what keys and values are in it?
Dictionaries support two methods which return the sort-of-lists of the keys
and values. We mention them here only for completeness.
Don’t forget that you can always convert a sort-of-list into a list with the
list() function.

394
What’s in a dictionary? ― 2
>>> en_to_es.items() Most useful method
dict_items([('mouse', 'ratón'), ('dog', 'perro'),
('cat', 'gato')])
(Key,Value) pairs/tuples

>>> for (english, spanish) in en_to_es.items():


... print(spanish, english)
...
ratón mouse
perro dog
gato cat
395

By far the best way to get at the contents of a dictionary is to use the
items() method which generates a sort-of-list of the key-value pairs as
tuples. Running a for… loop over this list is the easiest way to process the
contents of a directory.

395
What’s in a dictionary? ― 3
Common simplification

>>> list(en_to_es.items())
[('mouse','ratón'), ('dog','perro'),('cat','gato')]

396

Don’t be afraid to convert it explicitly into a list. Unless you dictionary is


huge you won’t see any problem with this.

396
Getting the list of keys

list() list of
dictionary
keys
{'the': 2, 'cat': 1, 'sat': 1, 'on': 1, 'mat': 1}

['on', 'the', 'sat', 'mat', 'cat']

397

Unfortunately when you convert a dictionary directly into a list you get the
list of keys not the list of )(key,value) pairs. This is a shame but is a
compromise for back compatibility with previous versions.

397
Is a key in a dictionary?

>>> en_to_es['snake']

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
KeyError: 'snake' Want to avoid this

>>> 'snake' in en_to_es

False We can test for it

398

Because of this conversion to the list of keys we can ask if a key is in a


dictionary using the in keyword without having to know its corresponding
value.

398
Example: Counting words ― 1

words = ['the','cat','sat','on','the','mat']

counts = {'the':2,'cat':1,'sat':1,'on':1,'mat':1}

399

Let’s have a serious worked example.


We might be given a list of words and want to count the words by how many
times they appear in the list.

399
Example: Counting words ― 2

words = ['the','cat','sat','on','the','mat']

counts = {} Start with an empty dictionary

for word in words: Work through all the words

Do something

400

We start by creating an empty dictionary. It’s empty because we haven’t


read any words yet.
Then we loop through the list of words using a standard for… loop.
For each word we have to do something to increment the count in the
dictionary.

400
Example: Counting words ― 3

words = ['the','cat','sat','on','the','mat']

counts = {}

for word in words:

✗ counts[word] += 1 This will not work

counter1.py
401

Unfortunately a simply increment of the value in the dictionary isn’t enough.

401
Why doesn’t it work?
counts = {'the':1, 'cat':1}

The key must already


be in the dictionary.
✓ counts['the'] += 1

counts['the'] = counts['the'] + 1

Key is not in

✗ counts['sat'] += 1
the dictionary!

counts['sat'] = counts['sat'] + 1
402

We cannot increment a value that isn’t there. Until the program meets a
word for the first time it has no entry in the dictionary, and certainly not an
entry with numerical value 0.

402
Example: Counting words ― 4

words = ['the','cat','sat','on','the','mat']

counts = {}

for word in words:

if word in counts:

counts[word] += 1

else:

Do something Need to add the key


403

So we have to test to see if the word is already in the dictionary to increment


it if it is there and to do something else if it is not. Note how we use the “if
key in dictionary” test.

403
Example: Counting words ― 5

words = ['the','cat','sat','on','the','mat']

counts = {}

for word in words:

if word in counts:

counts[word] += 1

else:

counts[word] = 1 counter2.py
404

print(counts)

That something else is to create it with its initial value of 1 (because we


have met the word once now).

404
Example: Counting words ― 6

$ python3 counter2.py

{'on': 1, 'the': 2, 'sat': 1, 'mat': 1, 'cat': 1}

You cannot predict the order of the

! keys when a dictionary prints out.


405

Dictionaries are unordered entities. You cannot predict the order that the
keys will appear when you print a dictionary or step through its keys.

405
Example: Counting words ― 7


print(counts) Too ugly

items = list(dictionary.items()) Better

items.sort()

for (key, value) in items:

print(key, value) counter3.py


406

Simply printing a dictionary gives ugly output.


We can pull out the (key,value) pairs and print them individually if we want.
Notice the use of pulling out the items, converting them into a list and then
sorting them.

406
Example: Counting words ― 8

$ python3 counter3.py

cat 1
mat 1
on 1
sat 1
the 2

407

407
Progress

Inspection methods dictionary.keys()


dictionary.values()
dictionary.items()

Testing keys in dictionaries if key in dictionary:


...

Creating a list of keys keys = list(dictionary)

408

408
Exercise 23

Complete exercise23.py to write


a function that reverses a dictionary.

{'mouse':'ratón', 'cat':'gato', 'dog':'perro'}

{'ratón':'mouse', 'gato':'cat', 'perro':'dog'}

10 minutes
409

409
Formatted output
$ python3 counter3.py

cat 1
mat 1
on 1 Ugly!
sat 1
the 2

cat 1
mat 1
on 1 We want data
sat 1 nicely aligned
the 2
410

We have one last topic to cover. The output from our word counter is not as
pretty as it might be. The last topic we will cover is Python text formatting.
Full details of the formatting system can be found online at
docs.python.org/py3k/library/string.html#formatspec

410
The format() method

>>> 'xxx{}yyy{}zzz'.format('A', 100)

'xxxAyyy100zzz'

'xxx{}yyy{}zzz'

'xxxAyyy100zzz'
411

In Python 3 the string type has a method called format() which takes
arguments and returns another string which is the original with the method’s
arguments inserted into it in certain places. Those places are marked with
curly brackets in the string.
Curly brackets are otherwise quite normal characters. It’s only the
format() method that cares about them.
In its simplest form, the format() method replaces each pair of curly
brackets with the corresponding argument.

411
String formatting ― 1

>>> 'xxx{:5s}yyy'.format('A')

'xxxA␣␣␣␣yyy'

'xxx{:5s}yyy ' {:5s}

s ― substitute a string
'xxxA␣␣␣␣yyy '
5 ― pad to 5 spaces
(left aligns by default) 412

The real fun starts when we put something inside those curly brackets.
These are the formatting instructions.
The simplest examples start with a colon followed by some layout
instructions. (We will see what comes in front of the colon in a few slides
time.) The number indicates how many spaces to allocate for the insertion
and the letter that follows tells it what type ob object to expect. “s” stands for
string.

412
String formatting ― 2

>>> 'xxx{:<5s}yyy'.format('A')

'xxxA␣␣␣␣yyy'

'xxx{:<5s}yyy ' {:<5s}

< ― align to the left (←)


'xxxA␣␣␣␣yyy '
413

By default strings align to the left of their space. We can be explicit about
this by inserting a left angle bracket, which you can think of as an arrow
head pointing the direction of the alignment.

413
String formatting ― 3

>>> 'xxx{:>5s}yyy'.format('A')

'xxx␣␣␣␣Ayyy'

'xxx{:>5s}yyy ' {:>5s}

> ― align to the right (→)


'xxx␣␣␣␣Ayyy '
414

If we want right aligned strings then we have to use the alignment marker.

414
Integer formatting ― 1

>>> 'xxx{:5d}yyy'.format(123)

'xxx␣␣123yyy'

'xxx{:5d}yyy ' {:5d}


d ― substitute an integer
(digits)
'xxx␣␣123yyy ' 5 ― pad to 5 spaces
(right aligns by default)
415

If we change the letter to a “d” we are telling the format() method to insert
an integer (“digits”). These align to the right by default.

415
Integer formatting ― 2

>>> 'xxx{:>5d}yyy'.format(123)

'xxx␣␣123yyy'

'xxx{:>5d}yyy ' {:>5d}


> ― align to the right (→)
'xxx␣␣123yyy '
416

We can be explicit about this if we want.

416
Integer formatting ― 3

>>> 'xxx{:>5d}yyy'.format(123)

'xxx␣␣123yyy'

'xxx{:<5d}yyy ' {:<5d}


< ― align to the left (←)
'xxx123␣␣yyy '
417

And we have to be explicit to override the default.

417
Integer formatting ― 4

>>> 'xxx{:05d}yyy'.format(123)

'xxx00123yyy'

'xxx{:05d}yyy ' {:05d}


0 ― pad with zeroes
'xxx00123yyy '
418

If we precede the width number with a zero then the number is padded with
zeroes rather than spaces and alignment is automatic.

418
Integer formatting ― 5

>>> 'xxx{:+5d}yyy'.format(123)

'xxx␣+123yyy'

'xxx{:+5d}yyy ' {:05d}


+ ― always show sign
'xxx␣+123yyy '
419

If we put a plus sign in front of the number then its sign is always shown,
even if it is positive.

419
Integer formatting ― 6

>>> 'xxx{:+05d}yyy'.format(123)

'xxx␣+0123yyy'

'xxx{:+05d}yyy ' {:05d}


+ ― always show sign
'xxx+0123yyy ' 0 ― pad with zeroes

420

And we can combine these.

420
Integer formatting ― 7

>>> 'xxx{:5,d}yyy'.format(1234)

'xxx1,234yyy'

'xxx{:5,d}yyy ' {:5,d}


, ― 1,000s
'xxx1,234yyy '
421

Adding a comma between the width and the “d” adds comma breaks to
large numbers.

421
Floating point formatting ― 1

>>> 'xxx{:5.2f}yyy'.format(1.2)

'xxx 1.20yyy'

'xxx{:5.2f}yyy ' {:5.2f}


f ― substitute a float
'xxx␣1.20yyy ' 5 ― 5 places in total

.2 ― 2 places after the point


422

Floating point numbers are slightly more complicated. The width parameter
has two parts, separated by a decimal point. The first number is the width of
the entire number (just as it is for strings and integers). The number after the
decimal point is the number of decimal points of precision that should be
included in the formatted output.

422
Floating point formatting ― 2

>>> 'xxx{:f}yyy'.format(1.2)

'xxx1.200000yyy'

'xxx{:f}yyy ' {:f}

'xxx1.200000yyy ' {:.6f}


423

The default is to have six decimal points of precision and to make the field
as wide as it needs to be.

423
Ordering and repeats ― 1
0 1 2
>>> 'X{:s}X{:d}X{:f}X'.format('abc', 123, 1.23)
0 1 2
'XabcX123X1.230000X'
0 1 2
Equivalent

>>> 'X{0:s}X{1:d}X{2:f}X'.format('abc', 123, 1.23)


0 1 2
'XabcX123X1.230000X'
0 1 2
424

What comes before the colon?


This is a selection parameter detailing what argument to insert.
The arguments to format() are given numbers starting at zero. We can
put these numbers in front of the colon.

424
Ordering and repeats ― 2

>>> 'X{0:s}X {2:f}X{1:d} X'.format('abc', 123, 1.23)


0 1 2
'XabcX 1.230000X123X'
0 2 1

>>> 'X{0:s}X{1:d}X{1:d} X'.format('abc', 123, 1.23)


0 1 2
'XabcX123X123 X'
0 1 1
425

We can also use them to change the order that items appear in or to have
them appear more than once (or not at all).

425
Formatting in practice
...
formatting = '{:3} {:1}'

for (word, number) in items:


print(formatting.format(word,number))

$ python3 counter4.py

cat 1
mat 1
on 1
sat 1
the 2 426

The script counter4.py is the same as counter3.py but with the new
formatting for its output.

426
Progress

Formatting string.format(args)

Numbered parameters {0} {1} {2}

Substitutions {:>6s}

{:+06d}

{:+012.7f}

427

427
Exercise 24

Complete exercise24.py
to format the output as shown:

[(Joe,9), (Samantha,45), (Methuselah,969)]

Joe 9
Samantha 45
Methuselah 969

5 minutes
428

428
And that's it! (And “it” is a lot!)
Text “if” test Reading files
Prompting Indented blocks Writing files
Numbers Lists Functions
Arithmetic Indices “Structured programming”
Comparisons Object methods Tuples
Booleans Built-in help “for” loops
Variables “for” loops Modules
Deleting names “Treat it like a list…” Dictionaries
“while” loop Values direct/via index Formatting
429

And congratulations!
You have completed an introductory course on Python. Well done.
It is only an introductory course and there is more. But do not let that
dishearten you; just take a look at what you have accomplished. You now
have a firm grounding to go further with Python or to start learning other
programming languages. (But the author would like you to stick with
Python.)

429
But wait! There’s more…

Advanced topics: Self-paced introductions to modules

Object-oriented programming in Python

430

If you do want more Python the UCS offers a selection of self-paced


courses on some additional language features and on various Python
modules to let you learn how to use Python for a specific purpose. We also
offer a taught course introducing you to the world of object-oriented
programming where you get to write your own methods and types.

430

You might also like