filter with dynamic value

Alex Martelli aleax at aleax.it
Fri Sep 14 09:28:26 EDT 2001


"Achim Domma" <achim.domma at syynx.de> wrote in message
news:9nsuqg$tmk$00$1 at news.t-online.com...
> Hi,
>
> I have something like this:
>
> ids = [(1,'abc'),(2,'abc'),(3,'xyz'),(4,'xyz')]
> comp = 'xyz'
>
> now I want to use filter to remove all items from ids which don't have
'xyz'
> as second value. I think the following should work:
>
> filter(lambda x: x[1]=='xyz')

No, because filter takes two arguments and you're calling
it with just one.  I suspect you mean something like:

    xyzids = filter(lambda x: x[1]=='xyz', ids)


> but how can I do this with an dynamic value ? If I try the following I get
> problems with the scope of comp :
>
> filter(lamdba x: x[1]==comp)

Use Python 2.2 (when it comes out -- it's now in alpha 3),
or, in Python 2.1, have as the first statement of your
module
    from __future__ import nested_scope

Or use list comprehensions instead, Python 2.0 and later:

    xyzids = [x for x in ids if x[1]==comp]

although this may be slightly slower than the filter (if
this is a bottleneck for your performance you'll need to
check this carefully).

Or use the good old default value trick, in any Python:

    xyzids = filter(lambda x, comp=comp: x[1]==comp, ids)

the default-value comp is evaluated once, when the lambda
is being executed to create the anonymous function, and in
the scope of the caller -- it's then bound to a name comp
that is an argument of the lambda and thus local to it.


There are more than these three solutions, of course, but
thse three are the simplest ones!


Alex






More information about the Python-list mailing list