Steve Willoughby steve at alchemy.com
Wed Sep 24 09:40:13 CEST 2008

Warning: this is going to look *a lot* better if you view it in a 
fixed-width font so things line up properly.

Both functions apply a function to a list of values, but they do so in 
different ways.

filter() applies a function to each element of a list in turn, returning 
a new list containing only those elements from the original list for 
which the function returned True (when given the element as the function 
argument).  In effect, it "filters" a list, like a physical filter would 
allow some particles to pass and catch others.  Only those elements 
meeting a certain criteria pass through the filter.

   def is_odd(i):
     return i%2 != 0

   a = [1, 2, 3, 4]
   b = filter(is_odd, a)

b now contains [1, 3]

The same thing could be done using lambda instead of defining a named 
function, of course:

   a = [1, 2, 3, 4]
   b = filter(lambda i: i%2!=0, a)

The reduce() function does something quite different.  It reduces a list 
of values to a single result by repeatedly applying the result of the 
transformation to the next one, adding a new element each time.  This 
way you get a cumulative effect.  The most obvious example of such a 
function (to me, anyway) is a factorial function.

   n! = 1*2*3*4*...*n

So you could implement the factorial function in Python using iteration, 
like this:

   def factorial(n):
     result = 0
     for i in range(1,n+1):
       result *= i
     return result

But we could also do this with reduce(), given a list of integers to 

   def product(x, y):
     return x * y

   a = [1, 2, 3, 4, 5, 6]
   b = reduce(product, a)

b is now 720.

What this will do is to start with the first two elements of a, and pass 
them to the product() function, then pass the result of that operation 
along with the next element to the product() function again, and so on 
until it has reduced the list to a single result:

   a =    [1, 2, 3, 4, 5, 6]
   product(1, 2) |  |  |  |   -> 2
      product(2, 3) |  |  |   -> 6
         product(6, 4) |  |   -> 24
           product(24, 5) |   -> 120
             product(120, 6)  -> 720

   or in other words, this computes (((((1*2)*3)*4)*5)*6) = 720

So our factorial function could have been implemented like this using 

   def factorial(n):
     return reduce(lambda x,y: x*y, range(1,n+1))


More information about the Tutor mailing list