Section 1 of 9

1 Before you start

Before you begin, take a few minutes to check what you already know and how confident you feel. You will see the same questions again at the end of the module — this helps both you and us measure what you have learned. Click an option for every question and confidence rating, then click Next to continue.

Pre-test

Inside a for loop, what does break do?

Pre-test

Inside a for loop, what does continue do?

Pre-test

You write for i, x in enumerate(["a", "b", "c"]): print(i, x). What does it print?

Pre-test

You write for i, x in enumerate(["a", "b", "c"], start=1): print(i, x). What does it print?

Pre-test

A break runs inside the inner of two nested for loops. Which loop stops?

Pre-test

Given ids = ["P1", "P2"] and ages = [54, 61], what does for x, y in zip(ids, ages): print(x, y) print?

Pre-test

What does [a * 2 for a in [1, 2, 3]] produce?

Pre-test

Given labels = {"A": 0, "B": 1}, what does {v: k for k, v in labels.items()} produce?

Pre-confidence

I can explain to a peer the difference between break and continue, and pick the right one for a given task.

Not at all confident
Fully confident
Pre-confidence

I can use enumerate to walk a list and report each item's position alongside its value.

Not at all confident
Fully confident
Section 2 of 9

2 Introduction

This module follows on directly from the previous control flow module. By now you can write an if/elif/else chain, walk a list with a for loop, and run a while loop until a condition flips. That is enough for most everyday code. This module covers two refinements that turn up constantly in real work:

  • Break and continue — exit a loop early, or skip the current item and go straight to the next one. Stopping at the first significant SNP is break; ignoring missing values is continue.
  • Enumerate — when you need both the position and the value as you loop, like printing a numbered list of samples or reporting which row of a table failed QC.

Try every snippet in the Python Scratchpad on the right. By the end of this module you will write a loop that walks a list, skips missing values, exits the moment it finds what it is looking for, and reports the position alongside the value.

Section 3 of 9

3 Loop control with break and continue

When working with loops, you don't always want them to run from beginning to end. Sometimes you need to alter their path using two distinct tools: break and continue.

Think of break as an eject button. When your code encounters a break statement, the loop stops instantly and completely terminates, with your program immediately moving on to whatever code follows the loop. This is incredibly useful when you have found exactly what you are looking for.

Continue in a Python loop.
Continue in a Python loop.

Can you predict what you will get from the code below:

Predict the output

Read the code carefully and type what you think it will print. Click Submit prediction for AI tutor feedback comparing your prediction against the real output, then click Reveal actual output to run the snippet yourself and see what happens.

Code
glucose_readings = [110, 125, 165, 130, 175]
for reading in glucose_readings:
    if reading > 160:
        print(f"First critical: {reading}")
        break
print("Done")

Try and practise the break keyword and the indent level

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
glucose_readings = [110, 125, 165, 130, 145]
for reading in glucose_readings:
    if reading > 160:
        print(f"Critical: {reading}")
        break

On the other hand, continue does something different. It skips the rest of the current pass and goes straight to the next item. The loop keeps running; only this one iteration is cut short. Use it to filter out items you do not want to process — missing values, blanks, anything that fails a quick sanity check.

Continue in a Python loop.
Continue in a Python loop.

Can you predict what will happen with the code below?

Predict the output

Read the code carefully and type what you think it will print. Click Submit prediction for AI tutor feedback comparing your prediction against the real output, then click Reveal actual output to run the snippet yourself and see what happens.

Code
readings = [120, -1, 145, -1, 130]
total = 0
for r in readings:
    if r < 0:
        continue
    total = total + r
print(total)

Try it out!

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
readings = [120, -1, 145, -1, 130]
for r in readings:
    if r < 0:
        continue
    print(f"Valid: {r}")

You can also combine both break and continue in a single code too!

Both break and continue affect only the loop they are written directly inside. If you have a loop nested inside another loop and you break, only the inner loop ends — the outer one keeps running.

Demonstration of break scope in nested loops..
Demonstration of break scope in nested loops..

From the example above, you can see two counters side by side. i (left) is the outer loop; j (right) is the inner loop. Each time j hits 3, break fires and j resets to 0. Notice that i keeps incrementing regardless. break only stops the loop it lives in, and the outer loop never sees it.

Section 4 of 9

4 Index tracking with enumerate

Most of the time, when you walk a list, all you care about is each item. But every so often you also need to know its position — you are printing a numbered list of samples, you want to flag which row of a table failed QC, or you need to write the position into a report. enumerate is the tool for that. It hands you both the position and the item on every pass, so you do not have to track the position yourself.

Enumerate returns both the indexes and values of items.
Enumerate returns both the indexes and values of items.

The syntax for enumerate is as follows:

readings = [120, 145, 110]
for i, r in enumerate(readings):
    print(f"Patient {i}: {r} mg/dL")

Try it out!

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
samples = ["S001", "S002", "S003", "S004"]
for i, sample in enumerate(samples):
    print(i, sample)

If you would rather count from 1 instead of 0 — natural for a numbered list shown to a human — pass start=1 to enumerate. enumerate(samples, start=1) gives you 1, 2, 3, 4 instead of 0, 1, 2, 3. The items are unchanged; only the counter shifts.

Predict the output

Read the code carefully and type what you think it will print. Click Submit prediction for AI tutor feedback comparing your prediction against the real output, then click Reveal actual output to run the snippet yourself and see what happens.

Code
samples = ["S001", "S002", "S003"]
for n, s in enumerate(samples, start=1):
    print(f"Sample {n}: {s}")
Section 5 of 9

5 Looping over two lists in parallel with zip

enumerate gives you the position alongside the value of one list.

zip does the same trick for two or more lists at once - it walks them in step. The shape is for a, b in zip(list_a, list_b). Each pass through the loop gives you the next item from each list. This is exactly how you pair a list of patient IDs with a list of ages, or a list of features with a list of labels later on.

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
patient_ids = ["P001", "P002", "P003", "P004"]
ages = [54, 61, 47, 72]

for pid, age in zip(patient_ids, ages):
    print(f"{pid}: {age} years")

# Three lists at once
weights = [82.0, 68.5, 75.1, 90.2]
for pid, age, weight in zip(patient_ids, ages, weights):
    print(pid, age, weight)
zip pairs two or more lists by position and lets a single loop step through those pairs together, one item from each list per pass.
zip pairs two or more lists by position and lets a single loop step through those pairs together, one item from each list per pass.
Section 6 of 9

6 List and dictionary comprehensions

A very common pattern is to walk a list, transform each item, and collect the results into a new list.

You can write that as a three-line for loop, but Python has a one-line shortcut called a list comprehension. The shape is [expression for item in iterable if condition], where the if part is optional. Read it left-to-right like a sentence: "the squared value for each a in ages where a is positive." Comprehensions are everywhere in real Python code, so being comfortable reading them matters.

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
ages = [54, 67, 71, 49, 82]
squared = [a ** 2 for a in ages]
print(squared)

seniors = [a for a in ages if a >= 65]
print(seniors)

labels = ["senior" if a >= 65 else "adult" for a in ages]
print(labels)
A list comprehension builds a new list in one line by evaluating an expression for each item in an iterable, optionally keeping only items that pass a filter condition.
A list comprehension builds a new list in one line by evaluating an expression for each item in an iterable, optionally keeping only items that pass a filter condition.

The same shortcut works for dictionaries. The shape is {key_expression: value_expression for item in iterable}. Two common uses are turning a list of pairs into a dict, and building a quick lookup table where the key and value are computed from the same source.

Try it out

Try this snippet in the Python Scratchpad on the right.

Try this snippet
pairs = [("P001", 54), ("P002", 61), ("P003", 47)]
lookup = {pid: age for pid, age in pairs}
print(lookup)

labels = {"A": 0, "B": 1, "C": 2}
inverse = {v: k for k, v in labels.items()}
print(inverse)
A dict comprehension builds a dictionary in one line by giving a key expression and a value expression for each item in an iterable, so you can turn pairs into a dict or compute a lookup table on the fly.
A dict comprehension builds a dictionary in one line by giving a key expression and a value expression for each item in an iterable, so you can turn pairs into a dict or compute a lookup table on the fly.
Section 7 of 9

7 Putting it together

The two tools in this module almost always combine with the for loop and the if-test you already know. A typical pattern looks like this: walk a list with a for loop, use an if to decide what to do with each item, use continue to skip the items you do not care about, use break to leave the moment you have what you want, and use enumerate when you also need the position.

Let’s practice putting the logic together.

Parsons problem · Scan patients until a critical reading

All the lines you need are in the Line bank on the left — some may be distractors you should leave behind. Drag the lines you need into the Your solution column on the right, in the correct order, then click Check.

Task: Loop over patient readings together with their index. Skip invalid (negative) entries. Stop at the first reading above 160 and announce it; otherwise print each valid reading and its patient index.

Line bank
  • break
  • print(f"Critical at patient {i}")
  • for r in enumerate(readings):
  • continue
  • pass
  • if r < 0:
  • print(f"Patient {i}: {r}")
  • for i, r in readings:
  • if r > 160:
  • readings = [110, -1, 145, 175, 130]
  • for i, r in enumerate(readings):
Your solution
  • Drop lines here, in order.

Good! Now, let’s try the worked example below:

Worked example · Find the first significant SNP and report its position

Work through this example in three stages. You unlock each stage only after the tutor confirms the previous one. Each stage removes more of the scaffolding — by the end you are writing it yourself.

Problem: Given a list of p-values, find the position (1-based) and value of the first p-value that is below 5e-8. Skip any None entries while scanning. If none is found, report "none".

Stage 1 · Study the solved example
Fully solved solution
p_values = [0.5, None, 0.01, 4.2e-8, 0.001, 1e-9]
result = "none"
for i, p in enumerate(p_values, start=1):
    if p is None:
        continue
    if p < 5e-8:
        result = f"position {i}, p = {p}"
        break
print(result)
Walk-through
  1. First we set a default result so we always have something to print, even if no significant p-value is found.
  2. Then we walk the list with enumerate(start=1) so the position is the human-friendly 1, 2, 3, … instead of 0, 1, 2, ….
  3. We use continue to skip the None entries cleanly, and break the moment we find a p below threshold so we do not keep scanning.
Section 8 of 9

8 Check your understanding

You have reached the end of the module. Try the same questions again — your answers here, paired with your pre-test answers, are how we measure what the module taught you. Answer every question and confidence rating, then click Submit and see results to view your score.

Post-test

Inside a for loop, what does break do?

Post-test

Inside a for loop, what does continue do?

Post-test

You write for i, x in enumerate(["a", "b", "c"]): print(i, x). What does it print?

Post-test

You write for i, x in enumerate(["a", "b", "c"], start=1): print(i, x). What does it print?

Post-test

A break runs inside the inner of two nested for loops. Which loop stops?

Post-test

Given ids = ["P1", "P2"] and ages = [54, 61], what does for x, y in zip(ids, ages): print(x, y) print?

Post-test

What does [a * 2 for a in [1, 2, 3]] produce?

Post-test

Given labels = {"A": 0, "B": 1}, what does {v: k for k, v in labels.items()} produce?

Post-confidence

I can explain to a peer the difference between break and continue, and pick the right one for a given task.

Not at all confident
Fully confident
Post-confidence

I can use enumerate to walk a list and report each item's position alongside its value.

Not at all confident
Fully confident
Section 9 of 9

9 Your results

Here is how your post-test answers compare with your pre-test answers. The pre/post pairing is the most reliable way to see what this module actually taught you.

Your score

Submit the post-test to see your results.

Muddiest point

What is the one thing from this module that is still unclear to you?

Rate this module

Overall, how would you rate this module?

How likely are you to recommend this module to a peer? (0 = not at all, 10 = extremely likely)