Since I wrote about listing comprehensions in Python a few weeks ago I've been getting feedback from people impressed with their ability, and looking forward to re-factoring their lawmaking using comprehensions rather than explicit loops.

Like anything though, there are situations where list comprehensions are useful, but besides situations where you're better served past using some other form. In this commodity nosotros'll take an example of where a part mill is the meliorate selection.

The example for this commodity is generating HTML colour codes in Python. If you needed to produce a smooth(ish) gradient in HTML, and you weren't too fussy near how information technology was encoded, and so you could knock something upwardly using a table and changing the bgcolor attribute. In this case a list comprehension would be a skillful arroyo:

def colourslist(reddish, green, blue, steps):   def f((start,finish), i, steps):   return start + i * (end-offset)/float(steps)    colours = [tuple([f(c,i,steps-i)   for c in [carmine,green,blue]])   for i in range(steps)]  render ["%02x%02x%02x" % (rgb) for rgb in colours]  print "<html><trunk>" print "<tabular array cellspacing=0 cellpadding=0><tr>" for color in colourslist((90,xc),(90,255),(90,ninety),200):  print "<td width=1px bgcolor=%south> </td>" % (colour) print "</tr></table>" print "</body></html>"              

Which gives us the expected output of:

Design patterns are at times a pretty contentious result among Python programmers. Those coming to Python from object oriented languages ofttimes tin't live without them, while those who came from languages without an accent on patterns tin can regard them equally a set of hammers for people who look at all programs as nails. Whatsoever you cull to telephone call information technology, the mill pattern is a useful tool to exist used on a range of problems.

The factory design involves writing a class that spits out other classes, depending on the parameters it is invoked with. A function manufacturing plant is similar, just instead of returning classes, we write a function that spits out other functions, customised to the situation. Since functions in Python are first grade objects, this is easy:

def colourfactory(ruby, green, blue, steps):  def cf(i):  def f((start,end), i, steps):  return start + i * (end-start)/float(steps)  rgb = tuple([f(c,i,steps-i) for c in [reddish,green,blue]])  return "#%02x%02x%02x" % (rgb)  render cf              

Calling colourfactory with the same parameters every bit colourlist will consequence in a function that is capable of generating the same results. For the previous example where we're using the same listing, this is less efficient, since you incur the added price of calling the function for every result, merely at that place are three principal situations where creating a part is a much better solution:

  • When you demand a sparse list — when you don't demand the whole list there's no reason to spend the fourth dimension generating it. A office factory allows y'all to simply utilise the results you lot need.
  • When you need the list out of order — if you desire to admission the results in a random society, it's easier and cleaner to generate them in the lodge that you lot demand them. A function factory approach will allow you gild the results whatever manner yous wish.
  • When keeping the whole list of results in memory is unfeasible — if yous've got to generate 100 million results and so yous've got to practise the work, but if you're simply using each ane once so at that place's no reason to shop them all in RAM. Using a office factory allows you to build your results piece by piece.

This last advantage can just as hands be accomplished by using a generator rather than a list comprehension, but it nevertheless has the disadvantage of needing to generate the items in a predetermined order — you can't hands have random access with a generator. An implementation of the colour edifice generator is in the next code sample:

def coloursgenerator(scarlet,green,bluish,steps):  for i in range(steps):  def f((get-go,end), i, steps):  return start + i * (end-start)/float(steps)   rgb = tuple([f(c,i,steps-ane) for c in [red,greenish,blue]])  yield "#%02x%02x%02x" % (rgb)              

Let's expect at an instance of where a function approach is more appropriate. Say nosotros've got a list of system loads, similar those generated by the uptime utility on UNIX or Linux, and nosotros want colour code them as a visual cue to how much load the system is nether. What we want is something that looks like the post-obit:

load average: 0.36 0.43 0.48
load average: 4.23 1.87 0.98
load average: iii.97 2.67 1.39
load average: 4.01 3.03 1.61

We'll utilise the load amounts as the per centum forth the gradient to colour the table cell (assuming that they max out at 5.00 for now). The implementation:

load_averages =   [[0.36, 0.43, 0.48],   [4.23, ane.87, 0.98],   [iii.97, 2.67, 1.39],   [iv.01, 3.03, ane.61]]  colourfunc = colourfactory((255,255), (255,0), (255,0), 500)  impress "<tabular array cellspacing=5 cellpadding=0>" for load in load_averages:  print "<tr><td>load average: </td>"  for 50 in load:  print "<td bgcolor=%due south>%s</td>" % (colourfunc(fifty*100),fifty)  print "</tr>" print "</table>"              

There'south no arroyo that's best 100 percent of the time, merely past knowing all of the options you lot tin be sure you lot've got the tools to write the best, most efficient and easiest to maintain code possible. There are situations where lists are definitely ameliorate, similar when you want to precompute every bit much of the data every bit possible so every bit not to irksome downward the execution of the algorithm, but in situations where y'all're doing random access and you lot only want some of the possible data you should try a part approach kickoff.