Python is known to be a multiparadigm language. This means that it borrows some elements from many programming disciplines --- functional, imperative, object oriented, etc. Few people use these methods, however. I, for one, gladly wrote for loops, when I could have written map. I wrote a few lines of code, but did not use list comprehension. This programming style was not because I did not know how to program in python, rather they were because I did not know much about functional programming.

Take the following program, for example:

def fun1(x):
return x + 3

def fun2(x):
return x * 3

def zero_matrix(size):
matrix = []
for i in xrange(size):
matrix.append([])
for j in xrange(size):
matrix[i].append(0)
return matrix

This is how you would write a program in C/C++/Java/C#. They can be easily translated to all these languages; the zero_matrix function, for example, can be written in Java code as (bear in mind that I am not a Java programmer):

ArrayList zero_matrix(int size) {
ArrayList<ArrayList> matrix = new ArrayList<ArrayList>();
ArrayList<double> tmp;

for(int i = 0; i<size; i++) {
tmp = new ArrayList<double>( );
for(int j = 0; j<size; j++) {
}
}
return matrix;
}

But the C type languages lack many of the features found in python --- they are not dynamic, scripted, and relatively not multiparadigm. Python, and Ruby, on the other hand are, and we can leverage some of their builtin methods.

Lambda Functions

Lambda (\lambda) or anonymous functions are a convenient way to write a function on one line.

List Comprehension

In mathematics we write S = {x \in \mathbb{N} | x < 100, x \ mod \ 9 = 0} to obtain the set of all natural numbers less than 100 that evenly divide 9; this is called list comprehension. For the sake of transition from the mathematical notation to python, lets look at how haskell does this. In haskell, you'd write the following to obtain the set S

S = [x <- [0..] | x < 100, x mod 9 == 0]

If we write this in a different font (note that looks like \in) we get

$$S = [ x \in \mathbb{N} | x < 100, x \ mod\ 9 = 0]$$

It is actually hard to see any difference between the way you write list comprehension in math vs. the way you write it in haskell.

Now let us look at how you write list comprehension in python.

S = [x for x in range(100) if x%9 == 0]

Aside from the location of various functions, the syntax is pretty much the same (note: python cannot deal with infinite list, but both mathematicians and haskell can). We can thus read the above python code as we do in English:

Generators

I lied when I said that python cannot deal with infinite lists, because it can --- they're called generators. Although it is ill advised to program using infinite lists in any programming language.

todo

todo

todo

todo

Applications

The following is some code that I have recently written to perform some matrix operations. Most are one liners, and the purpose of the functions should be known after an introductory course to linear algebra or classical physics.

Transpose

Given an m \times n matrix A, the transpose of A, conveniently written as A^T, is an n\times m matrix where A_{i,j}^T = A_{j,i} (A_{i,j} is the element in the i^{th} row and j^{th} column). Without using any functional techniques, one can go about coding this function as follows:

def transpose(matrix):
matrix_t = deepcopy(matrix)
matrix_shape = (len(matrix), len(matrix[0]))

for i in xrange(matrix_shape[0]):
for j in xrange(i+1, matrix_shape[1]):
matrix_t[i][j], matrix_t[j][i] = \
matrix_t[j][i], matrix_t[i][j]
return matrix_t

The function is not that complicated, and most likely as efficient as possible. When it comes to number of lines, however, the function is long --- at least compared to what we can do using functional programing.

def transpose(matrix):
return map(list, zip(*matrix))

def s_mul(self, s):
return map(lambda *row: list(map(lambda x: x+s, row)), *self.matrix)

return map(lambda (x,y): map(sum,zip(x,y)), zip(self.matrix, m))

Matrix Multiplication

Multiplication by a Scalar

def s_mul(self, s):
return map(lambda *row: list(map(lambda x: x*s, row)), *self.matrix)

Notice how both s_add and s_mul share most of the code, except for one function. We can therefore extract the majority of the code, and pass in the function as an argument.

s_apply(lambda x: x+s)
def s_mul(self, s):
s_apply(lambda x: x*s)
def s_apply(self, f):
return map(lambda *row: list(map(f,row)), *self.matrix)

ToDo

Dot Product

def dot(v_1, v_2=None):
v_2 = v_2 if v_2 else v_1
return sum(v_mul(v_1, v_2))

Norm

We Cheat.

def norm(v):
return sqrt(dot(v))

Other

Rot13

from string import lower

def rot13(s):
a = ord('a')
rot13_char x: chr((ord(x) - a + 13)%26 + a)
return "".join(map(rot13_char, lower(s)))