Property testing in lists

Alex Martelli aleaxit at yahoo.com
Wed Sep 13 05:14:15 EDT 2000


"Remco Gerlich" <scarblac-spamtrap at pino.selwerd.nl> wrote in message
news:slrn8rte3c.puc.scarblac-spamtrap at flits104-37.flits.rug.nl...
> Dan Brown wrote in comp.lang.python:
    [snip]
> > >>> N = [1, 10, 194, 148, -403]
> > >>> map (lambda x: x[1],filter (lambda x: x[0] % 4 == 1, map (None, N,
> > range(len(N)))))
> > [0, 4]
    [snip]
> N = [1, 10, 194, 148, -403]
> filter(lambda x,N=N: N[x] % 4 == 1, range(len(N)))
>
> It's more verbose than Matlab, but well, just make it into a function
once,
> and you'll never need to type it again...
>
> Python has nice ways to make a list of the *values* that have the
property,
> like filter() and list comprehensions in 2.0(beta), but not for the
indices
> I think. So just view it as a property of the index :-)

List comprehensions in Python 2.0 (currently beta) are nice ways to make
lists of indices just as well as list of values.

    [ i for i in range(len(N)) if N[i]%4 == 1 ]


But, of course, there are different approaches available, too, depending
on how you want to package this up as a function to be "made once".  If
you're often looking for a list of indices in situations where filter would
be just fine _except_ for the fact that it gives you a list of values
instead, for example, then the following function (which you can, if you
wish, easily make automatically available to all scripts you write; this
kind of things is done in site.py) may serve:

def filter_indices(function, list):
    return [ i for i in range(len(list)) if function(N[i]) ]

or, in older Pythons (you don't *have* to use lambda...:-):

def filter_indices(function, list):
    def select_by_index(i, function=function, list=list):
        return function(list[i])
    return filter(select_by_index, range(len(list)))

(Note that, if needed for performance, it would be reasonably
easy to write this as a small extension in C -- but, profile
to check this is indeed such a performance bottleneck, first...).

Armed with this simple tool, you can now call:
    filter_indices(lambda n: n%4==1, N)
and just get the indices rather than the values in situations
in which the builtin filter would otherwise be OK.


Alex






More information about the Python-list mailing list