"Collapsing" a list into a list of changes

Steven Bethard steven.bethard at gmail.com
Mon Feb 7 14:30:08 EST 2005


Francis Girard wrote:
> Is there someone on this list using this tool and happy with it ? Or is my 
> mind too much targeted on FP paradigm and most of you really think that all 
> the functions that apply another function to each and every elements of a 
> list are bad (like "reduce", "map", "filter") ?

I know there are definitely proponents for map and filter, especially 
for simple cases like:

     map(int, lst)
     filter(str.strip, lst)

Note that, unlike reduce, map and filter aren't really going to increase 
the number of function calls.  Consider the equivalent list comprehensions:

     [int(x) for x in lst]
     [x for x in lst if str.strip(x)]    [1]

The list comprehensions also require the same number of function calls 
in these cases.  Of course, in cases where a function does not already 
exist, map and filter will require more function calls.  Compare:

     map(lambda x: x**2 + 1, lst)

with

     [x**2 + 1 for x in lst]

Where the LC allows you to essentially "inline" the function.  (You can 
dis.dis these to see the difference if you like.)


As far as my personal preferences go, while the simple cases of map and 
filter (the ones using existing functions) are certainly easy enough for 
me to read, for more complicated cases, I find things like:

     [x**2 + 1 for x in lst]
     [x for x in lst if (x**2 + 1) % 3 == 1]

much more readable than the corresponding:

     map(lambda x: x**2 + 1, lst)
     filter(lambda x: (x**2 + 1) % 3 == 1, lst)

especially since I avoid lambda usage, and would have to write these as:

     def f1(x):
         return x**2 + 1
     map(f1, lst)

     def f2(x):
         return (x**2 + 1) % 3 == 1
     map(f2, lst)

(I actually find the non-lambda code clearer, but still more complicated 
than the list comprehensions.)

Given that I use list comprehensions for the complicated cases, I find 
it to be more consistent if I use list comprehensions in all cases, so I 
even tend to avoid the simple map and filter cases.


As far as reduce goes, I've never seen code that I thought was clearer 
using reduce than using a for-loop.  I have some experience with FP, and 
I can certainly figure out what a given reduce call is doing given 
enough time, but I can always understand the for-loop version much more 
quickly.


Of course, YMMV.

STeVe


[1] While it's not technically equivalent, this would almost certainly 
be written as:
     [x for x in lst if x.strip()]
which in fact takes better advantage of Python's duck-typing -- it will 
work for unicode objects too.



More information about the Python-list mailing list