Using functional tools

Alex Martelli aleax at aleax.it
Sat May 4 05:30:27 EDT 2002


Pekka Niiranen wrote:

> I would like to feed every second (or 3rd or 4th .etc) item in a list to
> a function.
> 
> list = ['a', 'b', 'c', 'd', 'e']
> 
> **some fancy map/filter -trick here**
> 
> => list = ['a', function('b'), 'c', function('d'), 'e']
> 
> Is there a (functional) way without using for or while -structures ?

List comprehensions are an eminently "(functional)" way -- consider that
Python took them from Haskell, surely a contender for "most functional
of functional languages":-).  However, Python's syntax for them was
indeed adapted to be more Pythonic, and in particular to use the
keyword 'for'.  Therefore, it's hard to say whether a list comprehension
meets your requirements, or not!

With a list comprehension, I'd do something like:

def feedOneOfN(sequence, function, N):
    def identity(x): return x
    funs = [identity]*(N-1) + [function]
    return [funs[i%N](x) for x in sequence]


> If I only manipulate every second line of a file with that function,
> is there a faster way than reading the whole file into a list ?:
> 
> list = open ("myfile.txt", "rb").readlines()

I suggest you do NOT use names of builtin types for your own variables:
it WILL eventually byte you.  Call this 'lines', NOT 'list'.

> **modify every 2nd line with set of functions**
> ** write the whole list into a new file**
> 
> The size of a file is max 2Mb.

For a file of that size, I think that, by far, the fastest approach
will be:

lines = open("myfile.txt").readlines()
for i in range(N-1, len(lines), N):
    lines[i] = function(lines[i])
open("newfile.txt", "w").writelines(lines)

The "functional" requirement results in a lot of useless calls to
identity (or other code that adds nothing to the task but does
eat some time and/or space), particularly for a large N.


Alex




More information about the Python-list mailing list