How to Browse Sequences

We already had a taste of what sequences are thanks to strings. But strings only include text. What if we need to store a bunch of numerical values? Or some strings together with numerical values?

Python provides two standard data types for containers where order matters: a mutable one, list(), and an immutable one, tuple(). They store an ordered sequence of value references. This means that if a list contains another list – of course this is possible – the inner one will not be copied inside the container, but a reference to it will be stored.

In Python a list is delimited by the characters [], while a tuple is delimited by characters ().

Here’s a list:

years = [2018, 2017, 2016, 2015]

Now, this is a tuple:

coordinates = (10.4, 20.2)

As we said, elements in lists and tuples are of arbitrary nature: they can be any kind of object, None included. They can be empty too.

Emptiness usually does not make much sense for tuples, given they cannot be modified once created. Instead it is very common to initiate an empty list which will be populated during an iterative process triggered by a while or for construct. Consider the following example:

The constructors list() and tuple() accept any kind of iterable as argument like strings or lists or tuples. They “listify” or “tuplefy” their arguments. For example, if a string is passed as argument to a list() function, the result will be a container where each character is stored separately:

At this point, you might ask yourself: why both tuples and lists? Aren’t lists enough? Apart from the difference in terms of mutability, there is a semantic difference in the usage of tuples and lists.

While tuples are used to store heterogeneous data structures, lists are ordered sequences of the same stuff. Take note that they have the same degree of freedom concerning data types, it’s just a matter of semantics.

Let’s consider the following scenario: it’s time for a quick ride on our bike and we would like to track our journey using an application installed on a smartphone. Let’s assume this application is written in Python. Every few seconds the application will ask the smartphone hardware for:

gps coordinate x

gps coordinate y

date and time

position = (x, y, dateTime)

This data will be then organized in a tuple. Since the length of the container does not need to be flexible (e.g. we know we won’t add a z index to it) but just to record a state through multiple values, a tuple is a good choice.

The application’s goal is to track a route, which is a sequence of multiple position instances. So, the application needs a container which is flexible and can be extended until the end of the journey: a list.

route = [position01,
position02,
position03]

Once finished, the route of the journey is saved on the smartphone memory. A standard table would suit very well the purpose.

Sequence Properties for Lists and Tuples

accessing

slicing

check containment

test equality

natural order

concatenation

List Methods

As we said, a list is a flexible container, which means that once created, it can be manipulated in multiple ways. Python provides a few specific methods for it

For Syntax

Python provides a for-loop syntax which is useful to iterate over a series of elements. Where while comes in handy when we need to keep doing something until a condition is matched, for is preferable when we need to browse a container. for can be used with any kind of iterable, which is a wider notion than sequences. Technically, an iterable can be non-sorted (as sets or dicts).

Here’s the general for construct:

for eachElement in iterable:
body

Note that the body is four spaces indented rightwards. for and in are protected keywords. eachElement is an identifier to which the body can refer to. Of course its name is arbitrary, it only needs to respect the standard rules for identifiers.

The iterable can be created either before the for opening statement or created on the spot. Meaning that this example:

myList = [1, 2, 3]
for eachNumber in myList:
print(eachNumber)

is equivalent to:

for eachNumber in [1, 2, 3]:
print(eachNumber)

This also means that we could invoke a function which is able to generate an iterable on the spot

Python provides a function that you will use very often in your coding routine: range(). This function returns an iterator –not a real list– which will provide a sequence of integers according to the following arguments

range(start, stop, step)

start and step are optional. start has to be addressed if step is defined. Take into account that, as for the slicing notation, the stop value is not included into the range created.

This function will make the iteration over a sequence of integer number easy and compact:

How can this be useful in a graphic design application? Consider the following scenario: you would like to create a pdf document of sixteen pages and write on each page a sequential page number. DrawBot can do that of course:

A for construct is the perfect companion of an .append()list method. It is very common to create a series of values starting from a pre-existing one. Like making an all-caps version of a word sequence:

Drawing Many Times in Two Directions

A single for construct allows repetition in one dimension. But, as we have seen with the previous example, other constructs can be used inside the for body. Which means that a second for loop can be nested into the first for loop. In this way the repetition becomes two dimensional.

If we need to draw a table or 90° based pattern, this technique becomes very handy. Consider the following drawing

This is a bidimensional matrix, it is a simple table. Each element of the matrix is called cell. Each cell of this matrix can be described by two indexes: the index of the column and the row to which the cell belong. If we explicit write each index to each cell we obtain

At this point we only need to define a size for the cell and we are able to draw the left column of the matrix