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.
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 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 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 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:
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.
I'll be on hackernews.