My elif conditional branching isn’t working!! [Python]

Contents
  1. The problematic program
  2. How to fix it
  3. Addendum (August 2022)

This article was automatically translated from Japanese using AI. The Japanese version is the authoritative version.

Have you ever wanted to branch on multiple conditions with an if statement, tried using elif, and found that although no error appears, the results somehow aren’t what you expected?
If so, the situation described below might be the cause.
For reference, since I made this mistake myself, I’m writing it down as a note.

The problematic program

The problem arises when you write two conditions in the if and elif statements and build a program that includes elif.

def trable(a, b):
    if a >= 10 & b >= 10:
        print("patern A")
    elif a >= 10 & b < 10:
        print("patern B")
    elif a < 10 & b >= 10:
        print("patern C")
    else:
        print("patern D")

trable(11, 11)
trable(11, 9)
trable(9, 11)
trable(9, 9)

When you run the program above, you might expect the cases to be sorted into patterns A, B, C, and D in order from the top, but the actual output is as follows.

patern A
patern B
patern C
patern B

What if we swap the order?

def trable(a, b):
    if a >= 10 & b >= 10:
        print("patern A")
    elif a < 10 & b < 10:
        print("patern B")
    elif a >= 10 & b >= 10:
        print("patern C")
    else:
        print("patern D")

trable(11, 11)
trable(9, 11)
trable(11, 9)
trable(9, 9)

If you swap the code for patterns B and C and write a program that you expect to output A, B, C, and D, the actual output is as follows.

patern A
patern D
patern D
patern D

elif itself is used as shown below when you want to define multiple conditions.

if 条件式A:
  条件式Aが真(True)となった場合の処理
elif 条件式B:
  条件式Aが偽(False)で、条件式Bが真(True)となった場合の処理
else:
  条件式Aが偽(False)で、条件式Bも偽(False)となった場合の処理

However, once the conditional expressions in the if and elif statements involve two conditions, the problem described above is likely to occur.
As a result, you don’t get the output you intended.

The tricky part is that no error is raised, so you can’t tell whether it worked until you actually look at the results.

How to fix it

When you want to branch into multiple cases using multiple conditions, avoid specifying multiple conditions in an elif statement.

def resolve(a, b):
    if a>= 10:
        if b >= 10:
            print("patern A")
        else:
            print("patern B")

    else:
        if b >= 10:
            print("patern C")
        else:
            print("patern D")

resolve(11, 11)
resolve(11, 9)
resolve(9, 11)
resolve(9, 9)

It becomes more cumbersome, but doing it this way produces exactly the output you expect.

Programming has unexpected pitfalls like this, so it’s a good lesson in carefully checking the code you write.

Addendum (August 2022)

It turns out the problem was not wrapping the conditions in parentheses.

def trable(a, b):
    if (a >= 10) & (b >= 10):
        print("patern A")
    elif (a < 10) & (b < 10):
        print("patern B")
    elif (a >= 10) & (b >= 10):
        print("patern C")
    else:
        print("patern D")

With this change, the branching worked correctly.
Alternatively, you can also solve it by writing and instead of &.

def trable(a, b):
    if a >= 10 and b >= 10:
        print("patern A")
    elif a < 10 and b < 10:
        print("patern B")
    elif a >= 10 and b >= 10:
        print("patern C")
    else:
        print("patern D")

& and and may seem the same, but & also acts as a bitwise AND, so in the original program

a >= 10 & b < 10

this apparently means a >= (10 & b) < 10, so with a=9 and b=9 the inequality becomes
9>=8<10, which evaluates to True.

It’s tricky, isn’t it…

Previous
Next