Programming in Python

Built-in Container Data Structures

Gerald Senarclens de Grancy

Terminology

Bug
Data
We usually think about lots of data => we need containers of data
Containers are objects that contain other objects
Python sequence types are containers
Alias
Alternative way of referring to an object

What's in a name? That which we call a rose by any other name would smell as sweet.

William Shakespeare

Python Lists

Aka. array, ArrayList, vector, ...

Mutable (can be changed in-place)

Contiguous memory - not a "linked list"

Sequence type

  • Support indexing and slicing: [index], [start:stop:step]
  • Aware of their length: len(.)
  • Membership testing: in
  • Can be iterated over: for ... in

Much more than a C-style array

  • Built-in functionality
  • In-place methods
  • Can be sorted

Optimized for usability, not speed

a_list = [3, 54, 2]
empty = []  # or `list()`

Working with Lists

#!/usr/bin/env python3

l = [3, 5, 1, 9]
ordered = list(range(8))
ordered = list(range(3, 8))
ordered = list(range(12, 2, -2))
print(len(l))
print(ordered.sort())
print(ordered)

Visualize execution

Performance

  • Don't worry about performance until it becomes a problem
  • But: understand the way lists work (contiguous memory)
  • Many inserts at beginning vs. reverse -> append -> reverse
ITERATIONS = 1000000

l = [7, 9, 3]  # initial content
for i in range(ITERATIONS):
    l.insert(0, 0)  # slow

l = [7, 9, 3]  # initial content
l.reverse()
for i in range(ITERATIONS):
    l.append(0)  # fast
l.reverse()

Assignment

Python assigns object references

first = [1, 2, 3]
second = first
second[1] = 50

Visualize execution

Shallow copy: list(.), [:] (slicing), l.copy()

first = [1, 2, 3]
second = first[:]  # or `list(first)` or `first.copy()`
second[1] = 50

Visualize execution

The Python Tutorial - More on Lists

Python 3 Video Tutorial - Lists

Tuples

Tuples are comparable to lists, but immutable

Sequence type

a_tuple = (3, 54, 2)
empty = ()  # or `tuple()`
t2 = (3, )  # creating a tuple with a single element requires trailing comma

Named Tuples

Allow to name their values

Values can also be accessed with dot notation

#!/usr/bin/env python3

from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])  # define new named subclass of tuple
p = Point(11, y=22)  # instantiate with positional args or keywords
print(p[0] + p[1])  # indexable like a regular tuple
print(p.x + p.y)  # fields also accessible by name

Visualize execution

Tuples

The Python Tutorial - Tuples and Sequences

Python 3 Video Tutorial - Tuples

Multiple Assignment

Pythonic way to work with "more than one return value"

Multiple values can be assigned at once

#!/usr/bin/env python3

result = "Joe, 117"
name, score = result.split(", ")
score = int(score)

Visualize execution

Seamless way to return "multiple values"

#!/usr/bin/env python3

def read_result(result):
    name, score = result.split(", ")
    return name, int(score)  # tuple is created "on the fly"

# ...

result = "Joe, 117"
name, score = read_result(result)  # tuple is unpacked into separate variables

Visualize execution

Also useful for swapping elements: a, b = b, a

Dictionaries

Aka. associative array or map

Collection of key-value pairs with unique keys

Similar to lists, but "keys" are used as indices

Key order is guaranteed to be insertion order (since Python 3.7)

Implemented as hash table (aka. hash map)

d = {"key1": "value1", "key2": "value2"}
empty = {}  # or `dict()`

Dictionaries

Example: Populate a dict

#!/usr/bin/env python3

d = {}
d["key1"] = "value1"
d["key2"] = "value2"
d["key1"] = "new value"

Visualize execution

Dictionaries

Example: Iterate over a dict

#!/usr/bin/env python3

d = {"telephone": "+43(0)316/380-1234",
     "email": "contact@uni-graz.at",
     "office": "Resowi, E3"}
for key in d:  # same as `for key in d.keys()`
    print(key, "--", d[key])
for value in d.values():
    print(value)
for key, value in d.items():
    print(key, "--", value)

Visualize execution

Dictionaries

Example: Iterate over Sorted Keys

#!/usr/bin/env python3

d = {"telephone": "+43(0)316/380-1234",
     "email": "contact@uni-graz.at",
     "office": "Resowi, E3"}
for key in sorted(d.keys()):
    print(key, "--", d[key])

Visualize execution

Sets

Collection of unique elements

Sets are useful wherever mathematical sets are useful

s1 = {1, 4, 5, 3, 1, 3, 5, 4, 3, 1, 3, 4}  # only 4 (distinct) elements
empty = set()  # {} would be an empty dictionary

Theory - Intersection

Intersection of two sets A and B, denoted by AB is the set containing all elements of A that also belong to B

[set intersection diagram]

Theory - Union

Union (denoted by ) of a collection of sets is the set of all elements in the collection

[set union diagram]

Example: Working with Sets

s1 = {1, 4, 5, 3, 1, 3, 5, 4, 3, 1, 3, 4}
s2 = {7, 8, 3, 9, 2, 6}
intersection = s1 & s2  # s1.intersection(s2)
union = s1 | s2  # s1.union(s2)
difference = s1 - s2  # s1.difference(s2)

Visualize execution

Matrices

Rectangular array of entries, arranged in rows and columns

Python does not offer a built-in type to efficiently deal with matrices

NumPy is the most popular third party package adding support for multi-dimensional arrays

sudo apt install python3-numpy  # global installation
pip install numpy  # in virtual environment

Example: Matrix Operations

#!/usr/bin/env python3

import numpy as np
print(f'{np.zeros([3,4])=}')
a1 = np.ones([4,3])
print(f'{np.ones([4,3])=}')
print(f'{3 * np.ones([4,3])=}')
a = np.arange(15).reshape(3, 5)
m = np.matrix(np.arange(6).reshape(2, 3))
print(f'matrix {m=}')
print(f'array {a=}')
print(f'{m * a=}')

print(f'transposed:\n{m.T=}')
print(f'inverse:\n{m.I=}')
Download np_matrix.py

NumPy is a library important enough to be dealt with in a designated session

Tentative NumPy Tutorial

Python 3 Video Tutorial - 2D Data

Questions
and feedback...