=5
xprint(f"{x} is {'even' if x % 2 == 0 else 'odd'}")
5 is odd
There’s more to control flow than if-else
statements and for
loops. Conditional expressions and loops with break
and else
clauses add expressivity and compactness, and the use of try-except
allows handling of errors.
Also known as ternary operator, this construct takes the form x if C else y
returning either x
or y
depending on condition C
.
Conditional expressions are more compact than if-else
clauses, and can directly assigned.
=5
xprint(f"{x} is {'even' if x % 2 == 0 else 'odd'}")
5 is odd
=6
x= "even" if x % 2 == 0 else "odd"
result print(f"{x} is {result}")
6 is even
The condition (C
) is evaluated first. If C
is True
, only x
is evaluated, otherwise only y
is evaluated. This allows syntax of the type x[0] if len(x) > 0 else None
to work seamlessly:
def first_element(x):
return x[0] if len(x) > 0 else None
= [1, 2, 3]
x print(f"first of {len(x)} elements is {first_element(x)}")
first of 3 elements is 1
= []
x print(f"first of {len(x)} elements is {first_element(x)}")
first of 0 elements is None
Note that next()
can provide a valid and more idiomatic alternative to x[0] if len(x) > 0 else None
as next(iter(x), None)
:
def first_element(x):
next(iter(x), None)
Loops in Python can also include an else
block, which is run if the loop runs without hitting a break statement.
def find_first_multiple_of_7(numbers):
for n in numbers:
if n % 7 == 0:
print(f"Found {n}")
break
else:
print(f"Not found")
23, 36, 94, 83, 18]) find_first_multiple_of_7([
Not found
23, 36, 91, 83, 21]) find_first_multiple_of_7([
Found 91
For each number n
, the function checks if n
is divisible by 7, in which case the if
block runs, breaking the loop.
If the if
condition never applies, the else
block runs instead.
try
, except
, else
and finally
The use of try
, except
, else
and finally
give us control over our software’s behavior when something goes wrong, allowing us to capture raised exceptions (i.e. errors).
The try
block contains the code that might raise an exception. If an exception is raised, the code in the corresponding except
block runs, where the exception is handled.
The except
block might return an error message or raise another exception providing more specific information on why the error happened. By combining different except
to capture different types of exceptions, we can customize the behavior for each exception type.
The else
block runs if no exceptions are raised, allowing us to execute code that depends on the successful completion of the try
block.
The code under finally
runs regardless of whether an exception occurred or not, and is typically used for cleanup actions that should always be performed.
def divide(a, b):
try:
= a / b
result except ZeroDivisionError as e:
print(f"Error: Cannot divide by zero. {e}")
return None
except TypeError as e:
print(f"Error: Invalid input type. {e}")
return None
else:
# runs only when no exceptions are raised
print("Division successful!")
return result
finally:
# runs regardless of whether an exception occurred or not
print("Execution of divide_numbers is complete.")
print(divide(10, 2))
Division successful!
Execution of divide_numbers is complete.
5.0
Let’s also see the case where the division by zero raises an exception:
print(divide(10, 0))
Error: Cannot divide by zero. division by zero
Execution of divide_numbers is complete.
None
And the case where the input is not a number:
print(divide(10, 'a'))
Error: Invalid input type. unsupported operand type(s) for /: 'int' and 'str'
Execution of divide_numbers is complete.
None