Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Controlling Program Flow with Conditionals and Loops

Hello! In the previous lesson, you used tuples, sets, and dictionaries to organize data. You could represent a task and check whether its action was permitted, but the program still needed instructions about what to do with the answer. This lesson adds those instructions: conditionals choose which code runs, and loops process multiple items without repeating the same code by hand.

You’ll use task records as examples because they make the decisions concrete. Everything here is a Colab simulation: printing that a task is ready does not perform an external action. Allow about 40–45 minutes to watch the selected video segments, read the short notebook excerpt, and run the examples.


Make a decision with if, elif, and else

A condition is an expression Python evaluates as true or false. Comparisons such as priority > 1, status == "done", and status != "done" produce Boolean values. Remember the distinction: = assigns a value to a variable, while == compares two values.

Watch the selected parts of Python Tutorial for Beginners 6: Conditionals and Booleans - If, Else, and Elif Statements by Corey Schafer. They establish how a condition controls an indented block and how Python chooses among alternatives.

Python Tutorial for Beginners 6: Conditionals and Booleans - If, Else, and Elif Statements

Watch the selected parts of Corey Schafer’s conditionals tutorial for the syntax and execution order of Python branches.

Begin with the if block, then watch value comparisons; stop that segment before the discussion of object identity. Watch else and elif, focusing on which blocks are skipped after a match. Finally, logical operators introduces and, or, and not.

Suppose a task has an action, a status, and a confirmation flag. The program should distinguish an unknown action from an already completed task, and it should not describe an unconfirmed task as ready.

permitted_actions = {"draft", "review", "schedule"}
task = {
    "action": "schedule",
    "status": "pending",
    "confirmed": False,
}

if task["action"] not in permitted_actions:
    print("Unknown action")
elif task["status"] == "done":
    print("Already completed")
elif not task["confirmed"]:
    print("Wait for confirmation")
else:
    print("Ready for simulated processing")

This prints Wait for confirmation. Python tests the branches from top to bottom. Once one condition is true, it runs that branch and skips the remaining branches. The final else needs no condition: it applies only when none of the preceding conditions matched.

The colon starts each branch, and indentation identifies the lines inside it. Four spaces per indentation level is the usual convention. An elif or else must align with its if, rather than being indented beneath it. If you wrote four separate if statements instead, Python would test all four independently; that is useful when several actions should happen, but not when you want one outcome from a set of alternatives.

You can combine checks when one condition is not enough. and requires both conditions to hold; or requires at least one; not reverses a Boolean result.

if task["action"] in permitted_actions and task["confirmed"]:
    print("Permitted and confirmed")

if task["status"] == "done" or task["status"] == "cancelled":
    print("No further processing needed")

Write the second comparison in full. task["status"] == "done" or "cancelled" does not mean “status equals either string”: the nonempty string "cancelled" counts as true on its own.

Conditions can also test whether a collection contains anything. For example, if tasks: runs when a list named tasks is nonempty; an empty list counts as false. Explicit comparisons are often clearer when a particular value matters: if priority == 0: distinguishes zero from other numbers rather than treating it merely as false.


Process a collection with for

A conditional handles one decision. A for loop lets the same block handle each item in a collection. Its loop variable takes the next item’s value on each pass, or iteration.

In Python For Loops - Python Tutorial for Absolute Beginners, Programming with Mosh shows both numbered repetition and iteration over collections. Watch these parts, then use a list of task dictionaries below so you can see the two ideas working together.

Python For Loops - Python Tutorial for Absolute Beginners

Watch the selected segments of Programming with Mosh’s for-loop tutorial to see how the loop variable changes and what range() supplies.

Watch loop basics and range arguments. Then skip ahead to iterable values for strings and lists. Focus on the difference between looping over generated numbers and looping directly over existing items.

Here, each task is one dictionary from the list. The count is initialized before the loop so it can accumulate a result across iterations.

tasks = [
    {"action": "draft", "status": "pending"},
    {"action": "review", "status": "done"},
    {"action": "schedule", "status": "pending"},
]

pending_count = 0

for task in tasks:
    if task["status"] == "pending":
        print(f"Pending: {task['action']}")
        pending_count += 1

print(f"Total pending: {pending_count}")

The loop prints the draft and schedule actions, then reports Total pending: 2. The last print is outside the loop because it is no longer indented. It runs once, after all tasks have been examined. If tasks were empty, the loop body would run zero times and the final count would still print as zero.

When you need a number of repetitions rather than items from a collection, use range():

for attempt in range(1, 4):
    print(f"Simulated attempt {attempt}")

This prints attempts 1, 2, and 3. The stopping value, 4, is excluded. Similarly, range(3) supplies 0, 1, and 2, while range(1, 6, 2) supplies 1, 3, and 5; the third argument is the step. Use for task in tasks when you need each task itself. You do not need a numeric index just to retrieve successive list items.

Other collections can be looped over too. Iterating over a dictionary gives its keys; .items() gives key–value pairs that you can unpack:

status_by_action = {"draft": "pending", "review": "done"}

for action, status in status_by_action.items():
    print(f"{action}: {status}")

A string supplies one character at a time. A set supplies its members, but, as you saw previously, you must not rely on their iteration order.


Skip an item or stop searching

A loop normally visits every item. Two statements change that behavior: continue skips the rest of the current iteration, while break exits the loop altogether.

Watch the early-exit example in the same for-loop tutorial. Pay particular attention to the indentation: break is inside both the conditional and the loop.

Python For Loops - Python Tutorial for Absolute Beginners

Return to Python For Loops - Python Tutorial for Absolute Beginners for an example of stopping a loop once a condition is met.

Watch early exit. Notice that later iterations do not occur after break, but code following the loop can still run.

Consider scanning a list for a schedule task. An unpermitted action should be skipped, as should a task already marked done. Finding a pending schedule task ends this particular search.

permitted_actions = {"draft", "review", "schedule"}
tasks = [
    {"action": "draft", "status": "pending"},
    {"action": "send", "status": "pending"},
    {"action": "review", "status": "done"},
    {"action": "schedule", "status": "pending"},
    {"action": "draft", "status": "pending"},
]

for task in tasks:
    if task["action"] not in permitted_actions:
        print(f"Skipping unpermitted action: {task['action']}")
        continue

    if task["status"] == "done":
        continue

    if task["action"] == "schedule":
        print("Found a pending schedule task")
        break

    print(f"Inspecting: {task['action']}")

print("Search finished")

The first draft is inspected. The "send" entry is skipped, and the completed review reaches continue without printing anything. When the loop finds "schedule", break prevents it from visiting the final draft. Search finished still prints because it is outside the loop.

Use break when finding one item settles the question. Do not use it when every eligible item needs processing; in that case, let the loop finish. continue is useful for excluding individual items without abandoning the rest of the collection.


Repeat while a condition remains true

A for loop is a natural fit for a collection or a known range of numbers. A while loop instead checks a condition before each iteration and continues only while that condition is true. This is useful when the number of repetitions depends on something that can change during the loop.

Read the beginning of the “While Loops” section in the Colab notebook Control Flow: If, For, and While Loops. It shows a changing number approaching a threshold.

Google Colab

Read the opening of the “While Loops” section in this Google Colab notebook to see a condition checked repeatedly as a value changes.

Find “While Loops” immediately after “2.4 - Example 4: Breaking out of For Loops.” Read the bounded example, through the explanation following the b < threshold_b code cell. Stop there: the following c != target cell deliberately demonstrates a loop that does not terminate, so do not run it.

The important wording is that a while condition is a condition for continuing, not a command that automatically stops the loop. Your code must change something relevant to that condition.

This example models an attempt that succeeds on the second try. There is no external request: the line setting success merely supplies a predictable outcome for the simulation.

attempt = 0
success = False
max_attempts = 3

while attempt < max_attempts and not success:
    attempt += 1
    print(f"Simulated attempt {attempt}")
    success = attempt == 2  # Fixed outcome for this demonstration

print(f"Success: {success}; attempts: {attempt}")

The loop runs twice. At the start of each pass, Python checks both requirements: there must be attempts left, and success must still be false. After the second pass, success is true, so there is no third pass. The attempt limit also ensures this loop would stop if success never occurred.

A common while-loop bug is to forget to update the value being tested. If neither attempt nor success could change, a condition that starts true could remain true indefinitely. For a fixed maximum number of attempts, for attempt in range(1, 4) is often simpler; use while when continuing depends on a changing condition, and keep a clear stopping path.


Takeaway

Conditionals select code according to Boolean conditions; an if/elif/else chain takes the first matching branch. for loops visit items or a range of numbers, with continue skipping one iteration and break ending the loop. while loops repeat only while their condition stays true, so they need an intentional way to stop.

You can now make a program choose among task outcomes and scan a list of tasks. Next, you’ll put reusable logic into functions, so the same decisions can be called with different inputs without copying the entire block of code.

Can't find a good explanation? Sign up and we'll make it for you

Sign up