Menu

Selection (IF)

Nested Selection

Nested selection means putting an if statement (or a whole if/elif/else structure) inside the block of another if. The inner selection is indented under the outer condition, so it is only reached when the outer condition is True. If the outer condition is False, the inner tests are never looked at at all.

Indentation is what makes nesting work: every line indented under an if belongs to that if. An else pairs with the if whose indentation level it lines up with, so you can tell which decision an else belongs to by looking at how far it is pushed in.

How nesting changes what runs

Imagine a cinema that checks age first. Only if the customer is old enough does it then check whether they have a ticket, because selling a ticket to someone too young to watch the film would be a wasted step.

age = int(input("How old are you? "))
has_ticket = input("Do you have a ticket? ") == "yes"

if age >= 12:
    if has_ticket:
        print("Enjoy the film")
    else:
        print("Buy a ticket first")
else:
    print("Too young for this film")

Output when the user types 14, yes:

How old are you? 14
Do you have a ticket? yes
Enjoy the film

The second if is indented one level in from the first, so it belongs to the outer block. Each else lines up with its own if: the outer else sits at the far left, and the inner else sits inside the outer block.

Flowchart of the cinema program: age >= 12 is tested first, and only if Yes is the nested has_ticket test reached, giving Enjoy the film or Buy a ticket first. No at the outer test gives Too young for this film.

Two tests, one condition

Often you can flatten the nesting into a single selection whose condition joins the tests with Boolean operators. The same three messages can be chosen with one if/elif/else that uses and and not:

age = int(input("How old are you? "))
has_ticket = input("Do you have a ticket? ") == "yes"

if age >= 12 and has_ticket:
    print("Enjoy the film")
elif age >= 12 and not has_ticket:
    print("Buy a ticket first")
else:
    print("Too young for this film")

Output when the user types 9, yes:

How old are you? 9
Do you have a ticket? yes
Too young for this film

Both versions print the same message for every pair of answers, because the logic is the same. Neither is more correct than the other: what matters is that the conditions give the right result for every input. Nesting reads well when the second test only makes sense after the first one has passed; here the flat version has to repeat the age test, which is one reason the nested version is easier to follow. A combined condition is shorter when the tests are independent โ€” write it the way you would say the rule out loud: "aged 12 or over and has a ticket".

Practise this