Python's Functional Training Wheels

Functional languages are all the rage these days. They're becoming
more popular in the startup community as teams are getting
smaller, and engineers are seeking more efficient languages to
program in (in terms of productivity). Personally, I love
python, which has some functional features, but I'm using
clojure more and more. The advantages of one vs the other are outside
the scope of this post.

However, a problem for most engineers is that picking up functional languages involves a
learning curve, and many times it's just not possible to switch to a new language where you're not as efficient.

The most difficult transition

There are many different features of functional languages which make them different from imperative or OO languages, such as being able to
pass functions as arguments. These require some adjustment, but are relatively easy. I've
found that the biggest adjustment when starting with a
functional language is that there are a few patterns that come up
again and again which your brain is just trained to write
for-loops for, and getting used to those patterns in a
functional setting is key to being able to develop 'flow'.

I used python before starting with clojure, and I found that I
gravitated towards using the functional features more often, and it
was very useful to develop patterns in python before moving to a
functional environment where there is no for-loop fallback.

Training wheels

Of course, Python has common functions such as map,
filter, and reduce, and using them is key. But those are covered in detail
elsewhere, and I won't cover them here.
More interesting to me were a
few functions from the itertools library, which as you'll
see, let you transform data structures without assignment.

groupby

groupby
groups elements together using a specified key. In
the itertools library, elements are only grouped if they are
contiguous, so you usually want to sort the list first. groupby
lets you, for example, construct a dictionary with the key being the
grouping criteria and the value being an arbitrary function of the elements in that group - in a single line. Here's an example where just the list function is used (see the docs - groupby returns a transient iterator for the list).

This example could be more efficiently done just by constructing the
dict off the bat and iteratively adding elements. However,
groupby is more useful when using a function which requires
the entire list to be present, for example when calculating
statistics about the list.

izip

izip
allows you to combine iterables into tuples, effectively transposing them:
This also allows you to modify dictionary keys and values in-line:
izip stops when one of the iterables ends, so you can use it with infinite generators such as cycle and repeat.

chain

chain is a very useful function that returns a new iterable that concatenates the elements of its arguments together (in some sense, it's the reverse of groupby). Combined with the * operator, it lets you flatten a list of lists.
Combined with map, you can extract lists from another iterable, and merge them:

Conclusion

My goal with this post was to share an observation: that incorporating
use of functional features into an imperative language like python makes it very easy to
transition to a more pure functional language. Since you can always fall back to an imperative style, it's easy to learn while still being productive. The key is to think about transforming data structures, without looping and without assignment.