Most programs' logic require conditional branching,  this means that some statements are only executed if a certain given  condition is met.  

Python offers an intuitive and user-friendly support for conditional branching  by use of  three essential keywords that  is if , elif and else.  We will explore each of these keywords and how they are used to form the branching blocks.

The If Block

This is the most basic and widely-used branching tool in Python,  it can be used alone to perform a task if a condition is met otherwise the program's execution jumps to the next statement after  it's block. The basic structure  of a standalone if statement is:

if condition:
    ...
    statement
    statement
    ...

The most common expressions which are typically used in the condition are those that evaluate to a boolean Value and they are used with any valid expression  , If the expression evaluates to True, the statements within the block are executed, otherwise they are skipped. If the expression used does not evaluate to either True or False, the boolean value of its results  is  evaluated, the following table shows Boolean values of possible expressions that can go in the condition:

non-zero number e.g 1,  -7,  20.0 True
Zero e.g 0,  0.0 False
non-empty String  True
empty string False

nonempty sequence e.g (0, 1, 2),  [1, 2, 3], {"a": "apple "}

True
empty sequence e.g (), [], {} False
any instance of Python type e.g class, function, types

True 

None False

This means that a block like the one shown below  will always be executed while the one just below it will  always be skipped:

#this block will always get executed
if 1:
   statement
   statement
#This block will never get executed!
if 0:
   statement
   statement

There is no reason why you should use  static values like those shown above  in the condition, most values that go in the condition are ones whose value is not known in advance  such as result of expressions,  user inputs,  or dynamic values for example return from functions.

ExampleEdit & Run
name = 'John'

if name == "John":
    print("Welcome")
Output:
Welcome[Finished in 0.01031598006375134s]

If the condition specified is not met the program will move on to the next statement , for example in the above case  , if the name entered is not "John Doe" the program will terminate.

ExampleEdit & Run
name = 'Isaac'

if name == "John":
    print("Welcome")
Output:
[Finished in 0.009967046789824963s]

Most of the times , we want to do something else if  the condition in the first if statement fails, this is where the elif block comes in.

The elif block

In most other programming languages, this block  goes by the name 'else if' but in python it is simply 'elif',  there is no limit to how many elif  blocks you can put below an if block, the only condition is that this block requires a preceding if block, this means that you cannot use an elif block without having used an if.  The elif blocks are used to chain conditions so that the one whose condition evaluates to True  first gets executed and the others below it are dropped without their condition  being tested. They are  used as follows:

if condition1:
    statement
    statement
elif condition2:
    statement
    statement
elif condition3:
    statement
    statement
elif condition4:
    statement
    statement
ExampleEdit & Run
num = 7

if num % 2 == 0:
    print("Even")
elif num % 2 == 1:
    print("Odd")
Output:
Odd[Finished in 0.009985603857785463s]

Another example:

ExampleEdit & Run
days = 31

if days == 30:
   print("April, June, September, November")
elif days == 31:
   print("January, March, May, July, August, October, December")
elif days == 28 or days ==29:
   print("February")
Output:
January, March, May, July, August, October, December[Finished in 0.01001273188740015s]

The else block

The else block  gets executed if all the preceding if and elif blocks fail, it does not require any condition. Without this block we might end up performing a lot of unnecessary condition checking.

The else block like  elif, cannot be used without a preceding if  block. This block is commonly used to handle events such as if an unexpected value is given,  e.g., user entering an invalid input .  It is used with preceding if  blocks  as follows:

if condition:
    block
else:
    block

And together with elif blocks as follows:

if condition 1:
   block
elif condition 2:
   block
elif condition 3:
   block
else:
   block

Our previous examples, now using the else block, might look as follows:

ExampleEdit & Run
num = 4

if num % 2 == 0 :
    print("Even")
else:
    print("Odd")
Output:
Even[Finished in 0.010071808937937021s]

 Another example: 

ExampleEdit & Run
days = 30 

if days == 30:
    print("April, June, September, November")
elif days == 28 or days == 29:
    print("February")
else:
    print("January, March, May, July, August, October, December")
Output:
April, June, September, November[Finished in 0.010563795920461416s]

You should be slightly careful when using the else statement, for example in the later snippet we are assuming that if the user didn't enter 30, 28 or 29 , then the user entered 31, if instead this is not the case say the user enters 500 as the input,  the program will still happily execute the statements inside the else block. So the most robust way to implement the above program is to explicitly use the if and elif blocks for the possible correct inputs and then use the else block to do something if the user did not enter one of the required values , we can for example print None.

ExampleEdit & Run
days = 57
if days == 30:
    print("April, June, September, November")
elif days == 28 or days == 29:
    print("February")
elif days == 31:
    print("January, March, May, July, August, October, December")
else:
    print(None)
Output:
None[Finished in 0.0104751440230757s]

The Short Hand Syntax

The if block can be used in one line , used this way, the header part i.e the part which contains the condition is separated with the statement to be executed with full colon as follows:

if condition : <block>
ExampleEdit & Run
name = 'John' 

if name == "John": print("Welcome!")
Output:
Welcome![Finished in 0.010596989886835217s]

When we use the else block as well in the short hand form, the full colon is not included,  we instead reorganize the statement such that the block comes before the if keyword as follows:

<block> if condition else <block>
ExampleEdit & Run
name = 'Jane'

print("Welcome") if name == "John" else print("You are not John.")
Output:
You are not John.[Finished in 0.010110002011060715s]

The short hand syntax is more suitable for simple conditional statements like the ones shown above , but can still be used with more than 2 conditions as shown

<block> if <condition> else <block> if <condition> else  <block> 

You should generally avoid this syntax and instead use the elif blocks to make the code easy to read and understand:

ExampleEdit & Run
days = 28

print("February") if (days== 28 or days == 29) else print("April, June, September, November") if days == 30 else print("January, March, May, July, August, October, December")
Output:
February[Finished in 0.010277758818119764s]

Interactively the above program will look like:

ExampleEdit & Run
days = 30

print("February") if (days== 28 or days == 29) else print("April, June, September, November") if days == 30 else print("January, March, May, July, August, October, December")
Output:
April, June, September, November[Finished in 0.010029422119259834s]

The pass Statement

The pass statement in Python is used when we want to exit  a block without doing anything. Yes that is correct, there are situations where you just want to "do nothing" if a certain condition is met, it is like we are telling the program execution to just pass the block.  It's syntax takes the following form:

if condition:
   pass
ExampleEdit & Run
age = 10

if 18 <= age<=100:
   print("You are an adult")
elif 5 <= age < 18:
   print("You are a minor:")
elif 0< age <5:
   print("You are a kid.")
else:
   pass
Output:
You are a minor:[Finished in 0.009932555025443435s]

In the above example if you enter a value which is not between 0 and 100, the program will "do nothing", because the else block which contains the else statement will be executed. You should note that the pass  statement does not tell the program to exit the  block, for example  if you put other statements below the pass statement, those statements will still be executed as usual. It is actually used mostly because python does not allow empty blocks.

The pass statement  is not unique to the branching blocks, you can use it with any other valid block such as functions or loops, you can even use it alone outside blocks.

Nested If statements

A nested if statement is where one or more if statements occurs inside of another. Nesting can take many shapes, there is actually no limit to the level of nesting, for example you can have an if statement inside another if statement, then another inside the inner one and so on.

the following is a possible form of nesting:

if <condition>:
   ...
   if <condition>:
       <block>
   elif <condition>:
       <block>
   else:
        <block>
   ...

Another example:

if <condition>:
   ...
   if <condition>:
       <block>
   elif <condition>:
       <block>
   else:
        <block>
   ...
elif <condition>:
     <block>
elif <condition>:
     ...
     if <condition>:
         ...
         if <condition>:
             <block>
         elif <condition>:
             <block>
         else:
             <block>
     else:
           <block>
else:
     <block>
      

You should generally avoid too much nesting since it can make the program less readable and hard to understand. Whenever the level of nesting gets deeper, you  can wrap some statement in a function , check on the The Zen of Python , to see other good practices to follow when programming in Python.