Loops and recursion
More fun with while loops and recursion
Factorial
The factorial function comes up frequently in probability and statistics (among
other disciplines). The factorial of n
(written n!
is the product of the
first n
integers; for instance,
3! = 3 * 2 * 1 = 6
How would we implement factorial using loops? How about recursion?
def factorial_loop(n: int) -> int: total = 1 while n > 1: total = total * n n = n - 1 return total def factorial_rec(n: int) -> int: if n <= 1: return 1 return n * factorial_rec(n - 1)
A list-shaped dictionary
Imagine we have a list formatted like this:
lst = ["Rhode Island", "Providence", "Vermont", "Montpelier", ...]
Weird list–what’s going on? It looks like someone tried to make a dictionary but messed up. How would we solve this problem?
We ended up with two versions of the code: one using a while loop and one using recursion. See the lecture capture for details.
def list_to_dictionary(l: lst) -> dict: result = {} index = 0 while index < len(l) - 1: result[l[index]] = l[index + 1] index = index + 1 return result
def list_to_dictionary_from_index(l: lst, res: dict, index: int) -> dict: if index + 1 >= len(l): return res else: res[l[index]] = l[index + 1] list_to_dictionary_from_index(l, res, index) def list_to_dictionary(l: lst) -> dict: return list_to_dictionary_from_index(l, {}, 0)
Mutation
Let’s go back to sorting for a moment. Instead of implementing our own sorting function, though, we’ll use the one built in to Python. For instance:
> l = ["doug", "alex", "brantley"] > l.sort() > l ["alex", "brantley", "doug"]
sort
is a method we can call on a list that sorts that list. Notice that,
just like our insertion_sort
function, it doesn’t return anything but it
modifies the list.
There’s another way to get a sorted version of a list:
> l = ["doug", "alex", "brantley"] > sorted(l) ["alex", "brantley", "doug"] > l ["doug", "alex", "brantley"]
What’s the difference? If we were to implement sorted
, what would its header
look like? It would take a list and return a list–and wouldn’t modify the list
we passed in!
Functions like sorted
allow us to write Python programs that are more similar
to the Pyret programs we wrote in CSCI 0111. Rather than storing data in
variables and then modifying the contents of those variables, we can avoid
modifying existing variables and instead create new data. Other functions that
work in this style are map
and filter
, which work just like their
counterparts in Pyret:
> list(map(lambda s: "cool " + s, ["doug", "alex", "brantley"])) ["cool doug", "cool alex", "cool brantley"] > list(filter(lambda s: not s.startswith("d"), ["doug", "alex", "brantley"])) ["alex", "brantley"] > list(map(lambda s: "HTA " + s, filter(lambda s: not s.startswith("d"), ["doug", "alex", "brantley"]))) ["HTA alex", "HTA brantley"]