The following code works as expected, and prints [[1,4], [2,5], [3,6]]
def trans(given): nrows = len(given) ncols = len(given[0]) matrix = [[0,0],[0,0],[0,0]] for i in range(ncols): for j in range(nrows): matrix[i][j] = given[j][i] return matrix a = [[1,2,3],[4,5,6]]However, the following code prints
[[3,6], [3,6], [3,6]]
:
def trans(given): nrows = len(given) ncols = len(given[0]) #matrix = [[0,0],[0,0],[0,0]] #commented this out and replaced it with the line below matrix = [[0]*nrows]*ncols for i in range(ncols): for j in range(nrows): matrix[i][j] = given[j][i] return matrix a = [[1,2,3],[4,5,6]]Why? Because the multiplication with
ncols
simply duplicates the references to the same list.
Here is the correct version:
def trans(given): nrows = len(given) ncols = len(given[0]) matrix = [[0 for _ in range(nrows)] for _ in range(ncols)] #initialize as separate lists for each row for i in range(ncols): for j in range(nrows): matrix[i][j] = given[j][i] return matrix a = [[1,2,3],[4,5,6]]
It is worth emphasizing again that there is a subtle difference between:
L.append(item)
(mutation)L = L + [item]
(re-binding)L
) is getting modified; while in the second case, a new list is getting created and L
is then associated with the new list.
Iterative algorithms so far
Multiplication: Iterative Solution
i
starts at b
i <- i-1 and stop when 0
result
)
result <- result + a
def mult_iter(a, b): result = 0 while b > 0: #iteration result += a #current value of computation: a running sum b -= 1 #current value of iteration variable return result
Multiplication: Recursive Solution
a*b = a + a + ... + a (b times) = a + (a + ... + a) (b-1 times for the value in the parentheses) = a + a*(b-1) (the latter term has the same structure as the original problem)
b=1, a*b=a
.
def mult(a, b): if b == 1: # base case return a else: return a + mult(a, b-1) # recursive step
Factorial
n! = n*(n-1)*(n-2)*...*1
n
do we know the factorial?
if n == 1: return 1 #base case
else: return n*factorial(n-1) #recursive step
Recursive function scope example
def fact(n): if n == 1: return 1 else: return n*fact(n-1) print(fact(4))
fact -> some code
n -> 4
n -> 3
n -> 2
n -> 1
1
2*fact(1)=2*1=2
3*fact(2)=3*2=6
4*fact(3)=4*6=24
fact(4)=24
Some observations:
Iteration vs. Recursion.
Iteration:
def factorial_iter(n): prod = 1 for i in range(1,n+1): prod *= i return prod
def factorial(n): if n == 1: return 1 else: return n*factorial(n-1)