# create a list of the numbers 0 through 9
data = [i for i in range(10)]
# create a list of the first 10 squares (0^2, 1^2, etc.)
[i*i for i in data]
# create a list of the first 5, non-negative odd numbers
[i for i in data if i % 2 == 1]
# create a list with 10 zeros
[0 for i in range(10)]
Write a Python function that computes the $n^{\mathrm{th}}$ fibonacci number, where: $$ \begin{align*} \mathrm{fib}(1) &= 1 \\ \mathrm{fib}(2) &= 1 \\ \mathrm{fib}(n) &= \mathrm{fib}(n-1) + \mathrm{fib}(n-2) \end{align*} $$ for all $n > 0$.
def fib(n):
'''
Given a positive integer n, returns the nth fibonacci number, where
fib(1) = fib(2) = 1
fib(n) = fib(n-1) + fib(n-2)
'''
assert n > 0, 'fib requires a positive number'
if (n == 1) or (n == 2):
return 1
return fib(n-1) + fib(n-2)
help(fib)
fibTrials = range(1, 15)
iterations = 100
# collect some measurements
import experimental
recursiveFibResults = experimental.timeTrials(fib, fibTrials, iterations)
# plot the results
%matplotlib inline
experimental.plot(fibTrials, [recursiveFibResults], legend=['recursive'])
Mutability, as always, can hurt our brain.
def addElem(elem, l=[]):
l.append(elem)
return l
addElem(10, [0, 1, 2])
addElem(1)
addElem(2)
Use the following idiom:
def addElem(elem, l=None):
if not l:
l = []
l.append(elem)
return l
addElem(10, [0, 1, 2])
myValues = []
addElem(1, myValues)
myValues
addElem(2, [])
Memoization saves time by caching the results of function calls.
def memo_fib(n, cache = {}):
'''
Given a positive integer n, returns the nth fibonacci number, where
fib(1) = fib(2) = 1
fib(n) = fib(n-1) + fib(n-2)
This function memoizes the results.
'''
assert n > 0, 'fib requires a positive number'
if (n == 1) or (n == 2):
return 1
if n not in cache:
cache[n] = memo_fib(n-1) + memo_fib(n-2)
return cache[n]
# take some measurements
memoizedFibResults = experimental.timeTrials(memo_fib, fibTrials, iterations)
# plot the results
experimental.plot(fibTrials, [recursiveFibResults, memoizedFibResults], legend=['recursive', 'memoized'])