# if example
= 100
x
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 chance
if, elif, else
Statementsif condition:
statement1
statement2elif condition: # else if
statement3else:
statement4 statement5
elif
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
= 100
x
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 statement2
= 10
time_left
while time_left != 0:
print(f"{time_left}...")
-= 1
time_left
print("blast off!")
10...
9...
8...
7...
6...
5...
4...
3...
2...
1...
blast off!
for
statementfor var in iterable:
statement1 statement2
This 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)
= 7 seconds_left
Tokyo
Delhi
Shanghai
São Paulo
Mexico City
for city in cities:
= False
need_to_break for letter in city:
if letter == "y":
= True
need_to_break break
print(letter)
if need_to_break:
break
T
o
k
break & continue
You 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
= 10
time_left = 4
abort_at
while time_left > 0:
print(f"{time_left}...")
-= 1
time_left 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
= "Hello class, my name is James"
s
for ch in s:
if ch == ",":
print("found a comma!")
break
else:
print("no comma found!")
found a comma!
# continue demo
print(cities)
= ["Chicago", "Mexico City", "Shanghai"]
visited
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.
= ["hello", "world"]
items = False
found
# 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":
= True
found break
print(letter)
if found:
break
h
while True:
do_something()if condition:
break
Similar 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.
= "hello"
s for i in range(len(s)):
print(i, s[i])
0 h
1 e
2 l
3 l
4 o
enumerate
Another 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
= range(12) # hmm?
r print(type(r))
<class 'range'>
# a common pattern, but we'll see a better way with enumerate
= 0
i for x in ["A", "B", "C"]:
print(i, x)
+= 1 i
0 A
1 B
2 C
enumerate
Another 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 -1
"Hello World", "W") find_r(
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 -1
"Hello world", "w") find_e(
6
"Hello world", "?") find_r(
-1
# note: a built-in exists and should be used in practice
= "Hello world"
s "w") s.find(
6
When you know exactly how many elements are in an iterable, you can use this syntax to “unpack” them into variables:
= (1, 2, 3)
tup = ["a", "b", "c"]
ll
= tup
x, y, z print(x, y, z)
1 2 3
# idomatic swap using unpacking
= 7
x = 8
y = y, x
x, y 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
statement3return value # optional
return
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 False
print(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():
pass
Type 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(
list[list[str]], # this parameter is a list of integers
a_list: int, # this parameter is a single integer
num: -> (
) 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:
pass
= find_value(3.0, "hello") x
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)