Learning objectives¶
After completing this practical, you will be able to:
iterate over lists and dictionaries using
forloopscombine loops with conditional logic
automate distance calculations between multiple cities
store and analyse results during iteration
stop loops early when a condition is met
choose between
forandwhileloops based on the task
Practical storyline¶
In the previous practical, you manually calculated distances between pairs of cities. In this practical, you will automate this process.
You will work with a small spatial dataset and:
replace repeated code with loops
compute distances for all city pairs
identify the most distant cities
calculate the median distance across the network
stop processing early when a condition is met
This mirrors a typical spatial data science workflow: from manual calculations to systematic processing.
Part 1 – Preparing the data¶
We start with a small dataset of cities and coordinates. To work efficiently, we combine names and coordinates into a dictionary.
Code¶
cities = ["Zurich", "Geneva", "Lugano"]
coordinates = [
[2682217, 1247945], # Zurich
[2499959, 1117840], # Geneva
[2720031, 1098728], # Lugano
]
city_data = {}
for i in range(len(cities)):
city_data[cities[i]] = coordinates[i]
print(city_data)
Tasks¶
Print the coordinates of Geneva using the dictionary.
Add one more city with coordinates of your choice to the original lists.
Explain in a comment why a dictionary is useful here.
Part 2 – Looping over structured data¶
You now have a dictionary that links city names to coordinates. Your goal in this part is to loop over that structure and produce readable output without hardcoding any city names.
Tasks¶
Write a loop that iterates over all cities in city_data and prints the city name together with its coordinates.
Use an f-string for formatting.
Modify the output to include coordinate units (e.g., km).
Add a comment explaining what the loop variable
cityrepresents.
Part 3 – Generating city pairs¶
To calculate distances systematically, cities must be compared pairwise. Your task is to generate all unique city pairs from the dataset, avoiding duplicate and self-comparisons.
Tasks¶
Write code that extracts all city names from city_data and uses nested loops to store each unique pair as a tuple in a list.
Explain in a comment why the inner loop starts at
i + 1.Verify that no city is paired with itself.
Count how many city pairs are generated and explain why this number makes sense.
Part 4 – Computing distances for all pairs¶
You now have a list of unique city pairs. The next step is to compute distances automatically for each pair and store the results.
For reference, the mathematical formulas are:
Euclidean distance:
Manhattan distance:
Tasks¶
Write code that loops over all city pairs, computes both Euclidean and Manhattan distances, and stores the results in a nested dictionary. Print a readable summary for each pair.
Explain in a comment why the distance calculation must happen inside the loop.
Inspect the structure of the
distancesdictionary and explain how it resembles an attribute table in GIS.
Part 5 – Tracking the maximum distance¶
Now you want to answer a question using your computed results:
Which two cities are the most distant from each other?
Tasks¶
Write code that iterates over the distances dictionary, checks the Euclidean distance for each pair, and updates a tracking variable to find the maximum distance.
Repeat the same logic using Manhattan distance instead of Euclidean.
Compare the results: Are the most distant city pairs the same? If not, why might that happen?
Explain why tracking values during iteration is more efficient than checking results afterwards.
Part 6 – Stopping early with break¶
Sometimes you already have your answer before the loop reaches the end. For example, stopping as soon as a distance exceeds a critical threshold.
Tasks¶
Write code that loops over all city pairs, computes the Euclidean distance, and uses break to stop the loop immediately if the distance exceeds 200000.
Explain what happens immediately after
breakis executed.Discuss situations in spatial data science where early stopping saves time.
Part 7 – Median and ordering¶
Loops are often used to prepare data for analysis. Here, you will extract the Euclidean distances you computed earlier and discover why data ordering matters for statistical calculations.
Tasks¶
Create an empty list called
euclidean_list. Loop through thedistancesdictionary from Part 4, extract the Euclidean distance for each pair, and append it to the list.Compute the median of
euclidean_listusing index logic (// 2).The Problem: If you run your median calculation on the list exactly as it was extracted from the dictionary, your result is likely incorrect. Why? What hidden assumption does the median rely on?
The Fix: Fix the calculation by sorting the data before computing the median using
sort()(list_sorted = list.sort()).
Part 8 – Optional – Fibonacci sequence¶
Tasks¶
Generate a Fibonacci sequence of exactly 10 values using a
forloop. Why does the loop start at index2?Generate a Fibonacci sequence using a
whileloop that stops only when a value exceeds100.
Reflection¶
Answer briefly in comments or markdown:
What did loops automate for you in this practical?
Where did conditions change program behaviour?
When would you use
forinstead ofwhile?
What comes next¶
Next, you will learn how to package logic into functions and reuse the same logic without copying code. Functions are the next step from working code to well-structured code. They allow you to turn patterns you used in this practical (for example distance calculation or median logic) into reusable building blocks.