Applying a function recursively

Chris Rebert clp2 at rebertia.com
Sat Sep 10 09:40:51 CEST 2011


On Sat, Sep 10, 2011 at 12:19 AM, hetchkay <hetchkay at gmail.com> wrote:
> Hi,
> I want to apply a "convert" function on an object as follows:
> If the object is of MyType type, invoke the passed in function.
> If the object is a dictionary, apply on the keys and values of the
> dictionary recursively.
> If the object is a set, list or tuple, apply on each element
> recursively.
> Else, leave the object as is.
>
> I wrote the following code:
> def convert(obj, func):
>   if isinstance(obj, MyType):
>      return func(obj)
>   elif isinstance(obj, dict):
>      return dict((convert(key, func), convert(value, func)) for key,
> value in obj.iteritems())
>   elif isinstance(obj, (list, tuple, set)):
>      return obj.__class__(convert(x, func) for x in obj)
>   else:
>      return obj
>
> Is there a better way to do this?

None comes to mind.

> Is there any way I can make this code faster?

Possibly, but it involves ignoring subclasses, and may not actually be
faster in your particular case (it comes down to additional function
calls vs. cost of if-elif-else chain). It would be along the lines of:

def convert_mytype(obj, func):
    return func(obj)

def convert_dict(obj, func):
    return dict((convert(key, func), convert(value, func)) for key,
value in obj.iteritems())

def dont_convert(obj, func):
    return obj

TYPE2FUNC = {MyType : convert_mytype, dict : convert_dict, ... }

def convert(obj, func):
    return TYPE2FUNC.get(type(obj), dont_convert)(obj, func)


As they say though, premature optimization is the root of all evil.

Cheers,
Chris
--
http://rebertia.com



More information about the Python-list mailing list