Lists, Dictionaries and Tuples
Lists, dictionaries and tuples are used to store collections of objects. They are differentiated from each other by the delimiter they use:
- []. A list. E.g.
["one","two"]
- {}. A dictionary. E.g.
{1:"one", 2:"two"}
- (). A tuple. E.g.
("one", 2)
Lists you should be very familiar with, as we all use lists daily. A dictionary is also straight forward—think of a regular dictionary where you have the word and then the meaning or definition of the word. In Python, the word is called a key and the definition a value.
Tuples are like lists, with a couple of differences.
Lists are designed to contain largely homogeneous data, much like in real life where you would have a shopping list or a to do list. By convention, Python list items should all be the same type (although Python doesn’t enforce this rule).
Tuples, on the other hand, are used to store heterogeneous data—("one", 2, [three])
is perfectly acceptable as a tuple, where it would be frowned upon as a list.
A single element tuple (singleton) is also written differently to a single element list:
lst = ["one"] # 1 element list
tpl = ("one",) # 1 element tuple with trailing comma
# to differentiate between
# a plain string ("one") or a
# functions parameter some_func("one")
Tuples, like strings, are immutable. Once they are created you can’t change them. Lists and dictionaries, however, are mutable and can be changed. Let me illustrate with some examples:
>>> lst = ["one"] # Set up a list, tuple and dictionary
>>> tpl = ("one",)
>>> dict = {0:"one"}
>>> lst[0] # All contain the same first element 'one'
>>> tpl[0]
'one'
>>> dict[0]
'one'
>>> lst[0] = "two" # List is mutable (can be changed)
>>> lst
['two']
>>> dict[0] = "two" # So is the dictionary
>>> dict
{0: 'two'}
>>> tpl[0] = "two" # Tuple is immutable. Can't change! Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> str = "one" # String is also immutable
>>> str[0] = "x"
Traceback (most recent call last): File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Here’s a screenshot of the exercise (your Python version will be different to the screenshots):

One last point on tuples vs. lists—tuples are often used for homogeneous data that the programmer doesn’t want changed by accident. So, if you have a list of items that should not be changed, it can be a good idea to use a tuple instead of a list.
Lists, Dictionaries and Tuples Useful Resources
- Introduction to Lists in Python
- Python Tutorial – More on Lists
- Python Tutorial – Tuples
- Python Tutorial – Dictionaries
The if Statement and Code Branching
Python, like most programming languages, has an if
statement that provides branching in your code. The syntax of Python’s if statement is as follows:
if [expression is True]:
# execute this code when True
else:
# execute this code when False
The else branch is optional:
if [expression is True]:
# only executes when True
# resume code execution
The expression can be anything that evaluates to True or False. A few examples:
if num >= 10:
if str == "Hello:
if this != that:
if SomeVar:
… and so on.
Take note of example 4 above—in Python, anything that does not equate to zero, Null, or an empty object is True. For example:
>>> s = 0
>>> if s:
... print("True")
... # Python returns nothing - statement is false
>>> s = 1
>>> if s:
... print("True")
...
True
>>> s = ""
>>> if s:
... print("True")
... # Nothing again - statement is false
>>> s = "Hello"
>>> if s:
... print("True")
...
True
Python includes a comprehensive range of boolean operators that you can use within your expressions:
- <. Less than
- <=. Less than or equal
- >. Greater than
- >=. Greater than or equal
- ==. Equal
- !=. Not equal
- is. Is a particular object
- is not. Isn’t a particular object
Boolean operations are also supported for negating and chaining expressions:
- or. Either expression can be True
- and. Both expressions must be True
- not. Negate the proceeding expression
Python also supports multiple branching using the elif (short for “else if “) statement:
if [exp1 is True]:
# execute if exp1 is True
elif [exp2 is True]:
# execute if exp2 is True
elif [exp3 is True]:
# execute if exp3 is True
# and so on ...
Python if Statement Useful Resources
Loops and Iterators
Loops and iterators both do the same basic thing—repeat a section of code until some condition is met. With a loop, the repetition can be any arbitrary code sequence, whereas an iterator steps through an iterable object.
An iterable object is an object that can be indexed (stepped through) in a sequential way. The most common iterable types in Python are the sequence types—strings, lists, tuples and ranges.
The While Loop
To create a program loop in Python, you use the while statement. For example, here is a very simple loop:
a = 1
while a < 5:
print(a)
a+=1
This should be easy to follow:
- Set the value of a to 1;
- Start a loop with the while statement;
- Print out the current value of a;
- Increment a; and
- Repeat while the expression “a < 5” is True.
If you run this code at the Python prompt, your output should look like this:

Python’s while loops are very useful and can be used for much more than simple tasks like printing out a variable. For example, the factorial (!) of any number is simply the multiplication of the number with all the preceding integers (so 4! is equal to 123*4).
Here’s how to calculate the factorial of 9 with a while loop:

In the first line I am using multiple assignment, which is a useful feature of Python’s programming syntax. The statement fact, mul = 1, 2 is a shorthand way of writing:
fact = 1
mul = 2
Line 3 is where all the magic happens. First, we multiply the current value of fact
by mul
and then we increment mul
by 1. We then print out the new value of fact
.
Breaking out of Loops
The break and continue statements allow you to exit a loop before the loop condition is met. Consider the following code:
a, b = 1, 1
while a < 5:
print("a =", a)
a +=1
while b < 5:
print("b =", b)
if b == 2:
b = 1
break
b +=1
The break
statement will only exit the currently running loop, so in the above example the break statement only exits the inner while loop. Let’s see what the output is when we run this code:

You can see that the break statement doesn’t affect the outer loop—it continues to run until “a < 5” is False. Because the inner loop always breaks when b is equal to 2, the inner while loop never completes.
The continue
statement, on the other hand, won’t execute any of the code after the continue, but instead it jumps to the next iteration of the loop. Consider the following code:
a = 0
while a < 5:
a+=1
if a == 3:
print("My favorite number is", a)
continue # Go to next iteration of loop
print("a =", a) # The continue statement will stop
# this from printing when a equals 3
Run this code and you should see a different string printed when a equals 3:

The break
and continue
statements can also be used inside a for loop.
Iterating with a For Loop
The for loop is designed to step through an iterable item. It takes the basic form:
for [item] in [iterable]:
As I said earlier in the chapter, the most common iterables are strings, lists, tuples and ranges. Here are some examples:
>>> word = "Hello"
>>> for char in word: # Step through each character
... print(char) # in the word
...
H
e
l
l
o
>>> lst = ["1","2","3"] # Step through each item
>>> for item in lst: # in the list
... print(item)
...
1
2
3
>>> tup = (1,"two", 3) # Step through each item
>>> for item in tup: # in the tuple
... print(item)
...
1
two
3
>>> for i in range(5): # The range function provides you
... print(i) # with a sequence of integers
...
0
1
2
3
4
>>>
This should be easy to follow. The range()
function we haven’t covered, but it’s basically an easy way of creating a sequence of numbers. More on the range()
function in the Python documentation.
Loops and Iterators Useful Resources
- Python Reference – Compound Statements
- Python Tutorial – More Control flow Tools
- Python Tutorial – the range() Function
Catching Errors in Python
Let’s say you have a simple function where you need to take the answer from a previous operation and divide it by 5:
ans = answer/5
print("Answer divided by 5 is", ans)
Seems straight forward, let’s try that out at the Python prompt:

So far, so good—but what if, instead of getting an integer, our function got handed a string? Let’s try that again in Python:

Oops! You will note that you didn’t even get to enter the final print()
statement before Python threw an error. If this happened in the middle of an important part of your code, it could crash your program with potentially disastrous results.
Luckily, Python provides an easy, but robust way of handling errors within your code with the try ... except
statement:
try:
# Try this piece of code
except:
# On error, execute this bit of code.
Let’s try that now with our previous example:

In this case, all is OK and we get the expected output. Let’s try it again, but pass in a string this time:

This code is better, but we still have no idea what caused the error. Lucky for us, Python also captures the type of error.
If you look closely at the first bit of code that threw the error, you will see this line:
TypeError: unsupported operand type(s) for /: 'int' and 'str'
In this case, Python is telling us that the bad input is throwing a TypeError. So let’s modify the code to make it a bit more descriptive:

This is only a very basic example of error handling. It’s also incomplete (the code above will still crash if answer is zero); however, more complex implementations of the try...except
statement build on these fundamentals. For more on the try...except
statement, see errors and exceptions in the Python documentation. You can also find a comprehensive list of built-in exceptions in the Python docs.
Errors in Python Useful Resources
Python Classes and Functions
The basic purpose of classes and functions is to group together pieces of related code. The major difference between the two is that a function does something whereas a class is something. For example, if Person
was a class, walk()
and eat()
would be functions.
Both classes and functions can contain other functions. If a function is inside another function, it’s called a sub-function. If a function is included inside a class, it’s called a method. Subclasses also exist, but they are created by a process called inheritance. We will get to inheritance in just a bit.
To define a function in Python, you use the def
statement:
def function_name([parameter list]):
# rest of function
To define a class in Python, you use the class statement:
class Someclass([argument list]):
# class constructor
init ():
# Constructor code
# class methods
def ...
You create subclasses that contain all the attributes and methods of another class using inheritance. Inheritance is an important concept in object-oriented programming. Inheritance helps prevent repetition in code, and it allows programmers to build complex programs from simpler building blocks.
To create a class that inherits from another class, you refer to the parent when defining the class:
class ChildClass(ParentClass):
This is easier to understand with an example—a simple Django form class:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100) email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
In this example, the class is inheriting from Django’s forms.Form
class, which make all the methods and attributes of the parent class (forms.Form
) available in the child class (subclass) ContactForm
.
This very brief introduction to classes and functions only scratches the surface of their full capabilities. The aim is simply to introduce them in a way that you will recognize what they are while you are learning Django. As Django uses classes and functions extensively, you will have plenty of opportunity to pick up more skills and understanding as you go.
Classes and Functions Useful Resources
Python Packages and Modules
To clearly organize large projects into logical units, Python structures code into modules and packages.
A module is the base unit of Python’s program structure. A module is a file with a .py extension that contains all the functions, classes and definitions pertaining to that module.
A package is a collection of modules all saved inside a package folder. The package folder must contain a file called __init__.py
for Python to be able to identify the folder as a package.
Let’s have a look at the Django project we created in the last chapter to see packages and modules in action:
\mfdw_site
init .py # This tells Python that
# mfdw_site is a package.
settings.py # The settings module for our project.
urls.py # The urls module for our project.
# ...
The Dot Operator
Dot notation is a common idiom in object-oriented programming. I like to think of the dot like a point because the dot points to something. In the case of Python, the dot operator points to the next object in the object chain. In Django classes, the object chain is like this:
package.module.class.method
Or in the case of functions:
package.module.function.attribute
Some real-life examples:
forms.Form
points to theForm
class in theforms
package.pages.apps.PagesConfig
points to thePagesConfig
class in theapps
sub-package of thepages
package. I.e., theapps.py
file in youpages
app.django.conf.urls
points to theurls
package inside theconf
package insidedjango
which is also a Python package!
This can sometimes get a bit confusing, but if you remember to join the dots (sorry, bad pun there), you can usually find out what the dot operator is referring to.