# if example
x = 100
if x < 0:
print("negative")
print("second line")
elif x == 0:
print("zero")
elif x == 4:
print("four")
else:
print("positive")positive
Python programs are made up of statements. Expressions are special types of statements that represent values.
Now we’ll look at statements related to control flow, deciding which lines of code will be executed next. Without them our programs would just execute one line after the next with no exception.
Perhaps the most jarring change for C/Java/JavaScript programmers: Python does not use braces.
Instead, indentation signifies code block boundaries.
from __future__ import braces
SyntaxError: not a chanceif, elif, else Statementsif condition:
statement1
statement2
elif condition: # else if
statement3
else:
statement4
statement5elif and else are optionalThis is a statement because you don’t write
x = if ...:
...
else:
...
else:
...
Instead, these lines of code are evaluated conditionally.
# if example
x = 100
if x < 0:
print("negative")
print("second line")
elif x == 0:
print("zero")
elif x == 4:
print("four")
else:
print("positive")positive
while statementwhile condition:
statement1
statement2time_left = 10
while time_left != 0:
print(f"{time_left}...")
time_left -= 1
print("blast off!") 10...
9...
8...
7...
6...
5...
4...
3...
2...
1...
blast off!
for statementfor var in iterable:
statement1
statement2This looks a bit different from C/Java.
Also, what is an iterable?
For now, just know that sequences are iterables, we’ll cover iterables soon.
cities = [
"Tokyo",
"Delhi",
"Shanghai",
"São Paulo",
"Mexico City",
"Cairo",
"Mumbai",
"Beijing",
"Dhaka",
"Osaka",
]
for city in cities:
if city == "Cairo":
# we don't need to print Cairo out
break
print(city)
seconds_left = 7Tokyo
Delhi
Shanghai
São Paulo
Mexico City
for city in cities:
need_to_break = False
for letter in city:
if letter == "y":
need_to_break = True
break
print(letter)
if need_to_break:
breakT
o
k
break & continueYou may have seen break and continue in other languages.
If so, they work the same way in Python.
break - exit a loop immediately
continue - immediately begin next iteration of loop
else statement after for or while - executes only if no break was called
# break/else demo
time_left = 10
abort_at = 4
while time_left > 0:
print(f"{time_left}...")
time_left -= 1
if time_left == abort_at:
print("Launch Aborted")
break
else:
# this only runs if we don't break
print("blast off!")10...
9...
8...
7...
6...
5...
Launch Aborted
s = "Hello class, my name is James"
for ch in s:
if ch == ",":
print("found a comma!")
break
else:
print("no comma found!")found a comma!
# continue demo
print(cities)
visited = ["Chicago", "Mexico City", "Shanghai"]
for city in cities:
# this is not a great use, what would you do instead?
if city in visited:
continue
print(f"I would like to visit {city}")['Tokyo', 'Delhi', 'Shanghai', 'São Paulo', 'Mexico City', 'Cairo', 'Mumbai', 'Beijing', 'Dhaka', 'Osaka']
I would like to visit Tokyo
I would like to visit Delhi
I would like to visit São Paulo
I would like to visit Cairo
I would like to visit Mumbai
I would like to visit Beijing
I would like to visit Dhaka
I would like to visit Osaka
continue is not used as often as break in practice, but can be useful if you want to skip part of a loop.
Given the somewhat less straightforward nature of a continue, a comment explaining your intent is a good idea.
items = ["hello", "world"]
found = False
# we want to exit as soon as an e is found in *either* loop
for item in items:
for letter in item:
if letter == "e":
found = True
break
print(letter)
if found:
breakh
while True:
do_something()
if condition:
breakSimilar to a do while loop in C/C++, where condition is checked after one iteration.
Another iterable!
range(stop) # goes from 0 to (stop-1)
range(start, stop) # goes from start to (stop-1)
Same rules as slice, always inclusive of start, exclusive of stop.
or as you’d write mathematically: [start, stop)
for x in range(5, 25):
print(x)5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Note: we'll see a better way to do what this loop does below.
s = "hello"
for i in range(len(s)):
print(i, s[i])0 h
1 e
2 l
3 l
4 o
enumerateAnother iterable, for when we need the index along with the object.
Gives us back two element tuples:
(index, element)
for i, letter in enumerate(s):
if letter == "w":
print(i)# same as above -- but less idiomatic & clear
for tup in enumerate(s):
if tup[1] == "w":
print(tup[0])A for loop can be described as iterating over an iterable:
for var_name in iterable:
statement1
statement2
...
An iterable is any object that can be iterated over. All sequences are iterable, what else is?
Another iterable!
range(stop) # goes from 0 to (stop-1)
range(start, stop) # goes from start to (stop-1)
Same rules as slice, always inclusive of start, exclusive of stop.
or as you might write: [start, stop) – we’ve seen this before with slicing
for x in range(12):
print(x)0
1
2
3
4
5
6
7
8
9
10
11
for x in range(8, 12):
print(x)8
9
10
11
r = range(12) # hmm?
print(type(r))<class 'range'>
# a common pattern, but we'll see a better way with enumerate
i = 0
for x in ["A", "B", "C"]:
print(i, x)
i += 10 A
1 B
2 C
enumerateAnother function that returns an iterable, for when we need the index along with the object.
enumerate(original_iterable) yields two element tuples: (index, element) for every item in the original.
# "incorrect" example
# find using range/len - as you might think to write it based on past experience
def find_r(s, letter_to_find):
for i in range(len(s)):
if s[i] == letter_to_find:
return i
return -1find_r("Hello World", "W")6
# find using enumerate - Pythonic, more efficient
def find_e(s, letter_to_find):
for i, letter in enumerate(s): # tuple unpacking
if letter == letter_to_find:
return i
return -1find_e("Hello world", "w")6
find_r("Hello world", "?")-1
# note: a built-in exists and should be used in practice
s = "Hello world"
s.find("w")6
When you know exactly how many elements are in an iterable, you can use this syntax to “unpack” them into variables:
tup = (1, 2, 3)
ll = ["a", "b", "c"]
x, y, z = tup
print(x, y, z)1 2 3
# idomatic swap using unpacking
x = 7
y = 8
x, y = y, x
print(x, y)8 7
A function is a set of statements that can be called more than once.
Benefits of functions:
def function_name(arg1: int, arg2: float, arg3: tuple) -> None:
"""
Description of function task
Parameters:
arg1: description of arg1
arg2: description of arg2
arg3: description of arg2
Returns:
Description of what this function returns, if anything.
"""
statement1
statement2
statement3
return value # optionalreturn may appear anywhere in a function body, including multiple times.
The first return encountered exits the function immediately.
Every function in python returns a value, None if not stated/reached.
def is_even(num):
return num % 2 == 0
print(is_even(3))False
# what happens if return is missing?
def bad_return(num):
if num > 10000:
return Falseprint(bad_return(1))None
pass statementCan be used whenever you need to leave a block empty. Usually temporarily.
if x < 0:
pass # TODO: figure this out later
else:
return y / 2 - x
def implement_me():
passType annotations are a newer Python feature. They exist to provide hints as to what types a function takes.
Python does not enforce these, think of them as documentation.
You will start seeing them in assignments and documentation, and we’ll discuss them more later in the quarter.
# I've broken this function into multiple lines, which is allowed
# due to the parentheses.
def find_value(
a_list: list[list[str]], # this parameter is a list of integers
num: int, # this parameter is a single integer
) -> (
int | None
): # this annotation "-> int | None" indicates return type can be int or None
pass
def find_value(a_list: list[str], num: int) -> int | None:
passx = find_value(3.0, "hello")Function comments should be done in the form of a docstring, i.e., a multi-line string (delimited by triple quotes) after the function header.
This comment must contain information specific to what a function does. It should also include a description of the purpose and expected input arguments, the expected output values, and how error conditions are handled.
Example:
def hypotenuse(a: float, b: float) -> float:
"""
This function solves Pythagorean theorem a^2 + b^2 = c^2
for the value of c.
Parameters:
a, b: the lengths of sides of a right triangle.
Returns:
The length of the hypotenuse.
"""
return math.sqrt(a**2 + b**2)