Data Structures and Control Flow¶
Once you can assign values and write functions, the next step is telling Python how to make decisions, repeat work, and organize collections of data.
Lists, tuples, sets and dictionaries¶
Python has several built-in data structures, each with a different purpose. More details can be found in the excellent Python Standard Library Documentation on sequences
Lists¶
Lists store ordered, changeable collections:
samples = ["steel", "glass", "polymer"]
samples.append("ceramic")
print(samples)
['steel', 'glass', 'polymer', 'ceramic']
samples[2] = "silica"
print(samples)
['steel', 'glass', 'silica', 'ceramic']
For sequences, such as lists and tuples, individual elements can be selected, called indexing. Indices always start at 0: The first element always has the index 0. The last element can be chosen by using a negative index which counts from the end: -1 is the last element.
Also, sub-ranges can be selected with two indices and a colon ':' called slicing. The specified indices define the first element to include until the element specified by the second index, but not including it!
It is also easy to generate a list with range:
Tuples¶
Tuples also store ordered values, but they are typically used for fixed groups of values (read-only):
This will give an error:
dimensions[1] = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
The above tuple can only be changed by composing a new tuple using the '+' operator for concatenation:
Where (3,) is a tuple with a single element and dimensions[:1] indicates a slice of the dimensions tuple from the beginning until the first element (but not the second which has index 1). While dimensions[2:] will give a slice of the tuple from the third element (index 2) until the end.
Strings¶
Coming back to strings for a moment, since they behave like tuples of characters in Python.
Strings also can not by changed directly but need to be rebuild. Concatenation works with them as well:
There is a very comprehensive library of methods that can be used with strings and come in handy very often:
# Removing whitespace, aka. 'trimming'
text = " hello "
text.strip() # "hello"
text.lstrip() # "hello "
text.rstrip() # " hello"
# Splitting strings
text = "apple,banana,orange"
text.split(",") # ["apple", "banana", "orange"]
# Joining strings
words = ["apple", "banana", "orange"]
", ".join(words) # "apple, banana, orange"
# Checking contents
text = "hello123"
text.isalpha() # False (contains numbers)
text.isdigit() # False
text.isalnum() # True
# Finding substrings
text = "hello world"
"world" in text # True
text.find("world") # 6
text.startswith("hello") # True
text.endswith("world") # True
Formatting¶
So called f-strings are a very powerful tool for composing messages and for debugging:
name = "Bob"
age = 23
print(f"My name is {name} and I am {age} years old.")
print(f"{name=}, {age=}")
Note: Sometimes, trouble may be caused by strings accidentally used with code designed for sequences: It will often just work but will not give the expected result. We come back to that later, after loops.
Sets¶
Sets store unique values (no duplicates can exist) and are useful for quick membership tests:
They are very close to sets in the math and support operations like intersection, union and difference.
Performance: For very large sets of values, sets are faster than lists since the fundamental internal are different: Instead of checking each item, they use a hash function to get the memory location of values in the same way a hash table (dict) does.
Dictionaries¶
Dictionaries map keys to values, also called associative arrays in computer science. They are very powerful and widely used in Python:
They are useful whenever labels matter as much as the values themselves. They can be modified and keep the order of items as they were added. Dictionaries can have unique keys only, same as a set and in contrast to lists and tuples which may have many duplicate elements.
Conditionals¶
Use conditionals when your program should behave differently depending on a value:
temperature = 18
if temperature < 0:
print("Freezing")
elif temperature < 20:
print("Cool")
else:
print("Warm")
This pattern appears everywhere: validating inputs, checking files, handling errors, and controlling workflow.
Loops¶
Loops let you repeat an operation.
for loops¶
Use for when iterating over a sequence:
while loops¶
Use while when repetition depends on a condition:
Pitfall: accidentally treat a string as a sequence of items¶
def print_items(items):
for item in items:
print(item)
# Intended usage:
print_items(["apple", "banana", "cherry"])
Why this happens: - A string is a sequence of characters - The loop iterates over each character instead of treating "apple" as one item - Fix: use isinstance()
def print_items(items):
if isinstance(items, str):
items = [items] # treat as single item
for item in items:
print(item)
List comprehensions¶
List comprehensions are a compact way to build a list from another iterable:
They are powerful, but clarity still matters. If a comprehension becomes hard to read, a normal loop is often the better choice.
Error and exception handling¶
Real code should fail in understandable ways. A basic try / except
structure helps:
text = "42.2" # some user input
try:
value = (text)
except ValueError:
print("Converting '{text}' failed!)"
Use exception handling to react to expected failure modes, such as invalid input, missing files, or parsing problems.
Recursion¶
Recursion means a function calls itself. It is useful for some problems, but it is not always the clearest choice for beginners:
It is worth understanding the idea, even if loops remain the more common tool in daily work.
Invocation Tree Debugger¶
A very helpful tool for visualizing the recursion mechanism with your custom code: enter it the code box right-hand side and press play. It's source and some more example code is on its GitHub project page.
Practice ideas¶
- Create a list of numbers and print only the even ones.
- Build a dictionary that stores a few measurements by name.
- Write an
if/elif/elseblock for a grading scale. - Convert a
forloop into a list comprehension and compare readability.