
# Simple clear conditional expressions
n = 12
"odd" if n%2==1 else "even"
sign = 1 if n >= 0 else -1

# Simple clear list comprehensions
#
[i * i for i in range(5)]
[s.lower() for s in ["Hi", "Bye"]]
[num for num in [1, -2, 3, -4, 5] if num > 0]
[(i,j) for i in range(10) for j in range(i)]

# List comprehensions make it possible to write very concise code. BUT I don't write
# ones like these matrixMult versions.  I think they are too hard to read and debug.
# I use comprehensions only for simple things like those above.
#
M1 = [[1,2,3], [3,4,5]]
M2 = [[5, 10, 20], [100, 200, 1000]]

def matrixMult(A, B):
    return [ [sum([ A[i][j] * B[j][k] for j in range(len(B))]) for k in range(len(B[0])) ] for i in range(len(A))]

def matrixMult2(A, B):
    # Multiply row by (transposed w/zip) col
    return([[ sum([ a*b for (a,b) in zip(row,col) ]) for col in zip(*B) ] for row in A ])






