Monday, 18th October 2010
I had known about Python list comprehensions for a while, but had avoided them, thinking them too complicated (to write and to read) and that I could achieve whatever list comprehensions achieve without them (which is true). However, now I have got the hang of using them, I find them the one of the most useful techniques in Python. I sometimes find myself replace quite long loops or whole functions with a single line list comprehension. I have even attempted to reduce Conway's Game of Life to a single line of Python using list comprehensions.
You can find good guides to list comprehensions elsewhere on the internet, but briefly, they generate a list using one or more for loops with optional conditions. For example, if you want a list of the first five square numbers: [1, 4, 9, 16, 24], you could use a for loop.
squares =  for n in range(1,6): square.append(n**2)
But you can do in a single line with a list comprehension:
[n**2 for n in range(1,6)]
A real-life example of when I used a list comprehension was to built a list of all the codons (triplets of nucleotide bases):
bases = ['U', 'C', 'A', 'G'] codons = [a+b+c for a in bases for b in bases for c in bases]
List comprehensions can be used to construct lists of arbitrary complexity and it can be very tempting once you get the hang of them, though I'm not sure it makes for very readable code. Below is some code I wrote to compress a list such that the first item in my new list was the average of the first ten items in the original list, the second was the average of the next ten items and so on. It's written such that I can change the 'bin size' from ten to whatever I want.
data = [10, 13, 15 ...] # Several thousand numbers bin = 10 compressed_data = [float(sum(data[n*bin:(n+1)*bin]))/bin for n in range(len(data)/bin)]
Whether this is particularly readable is debatable.