Simpler mapping of lists

Erwin S. Andreasen erwin at andreasen.com
Tue Aug 20 18:07:41 CEST 2002


I often find myself applying a very simple operation to each element
of a sequence. In those cases the list comprehension syntax or map
takes up too much space. For example:

l2 = [x[1] for x in l]
l2 = map(lambda x:x[1], l)

With the trivial class below, you can write:

l2 = each(l)[1]

or:
l = ['foo', 'bar']
l2 = each(l).upper()

The each class will forward the function calls to each element of its
list, and return the result.

The class could also be easily extended to work on dictionaries, so
you could say:

d2 = each(d).upper()

to create a new dictionary where each value of d was turned into
upper-case.

The forwarding works only once. So this won't work:

each(file('/etc/passwd').upper().strip())

You could, I suppose add a "depth" keyword parameter to the
constructor of each which would make it return another each object
width depth-1, as long as depth > 1. Or you could nest the each calls. 
But that seems to detract from the simplicity of this class.

If you add the explicit self=self to __getattr__, and change the */**
to apply, then this class should also work for those few, stubborn
1.5.2 users.


class each:
    """
    Given a sequence, each will return an object that will apply all
    actions to this object to each of the elements in the sequence.
    """
    def __init__(self, l):
        self.l = l

    def __coerce__(self, other):
        return None

    def __getattr__(self, name):
        def wrapper(*args, **kwargs):
            return [getattr(x, name)(*args, **kwargs) for x in self.l]
        return wrapper

    def __repr__(self):
        return '<each %r>' % self.l


-- 
===============================================================
<erwin at andreasen.org>                           Herlev, Denmark     
<URL:http://www.andreasen.org/>                             <*>   
===============================================================




More information about the Python-list mailing list