Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder2.enfer-du-nord.net!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'elif': 0.04; 'type,': 0.07; '(it': 0.09; 'dict': 0.09; 'received:209.85.160.174': 0.09; 'received:mail- gy0-f174.google.com': 0.09; 'am,': 0.12; 'def': 0.15; 'dictionary,': 0.16; 'possibly,': 0.16; 'set,': 0.16; 'subclasses,': 0.16; 'subject:function': 0.16; 'tuple,': 0.16; 'cc:addr:python-list': 0.16; 'wrote:': 0.16; 'cheers,': 0.18; 'cc:no real name:2**0': 0.20; 'wrote': 0.20; 'this?': 0.21; 'cc:2**0': 0.22; 'header:In-Reply-To:1': 0.22; 'dictionary': 0.23; 'sep': 0.23; 'vs.': 0.23; 'code': 0.25; 'function': 0.27; 'sat,': 0.28; 'mind.': 0.29; 'message-id:@mail.gmail.com': 0.29; 'cc:addr:python.org': 0.30; 'lines': 0.30; 'invoke': 0.30; 'key,': 0.30; 'chris': 0.32; 'values': 0.32; 'list': 0.32; 'hi,': 0.32; 'actually': 0.33; 'there': 0.33; '...': 0.34; 'follows:': 0.34; 'function.': 0.34; 'keys': 0.34; 'root': 0.34; 'apply': 0.35; 'received:209.85.160': 0.35; 'object': 0.35; 'optimization': 0.36; 'none': 0.37; 'element': 0.37; 'else,': 0.37; 'passed': 0.37; 'but': 0.37; 'received:google.com': 0.38; 'received:209.85': 0.38; 'skip:o 20': 0.38; 'subject:: ': 0.39; 'case': 0.39; 'leave': 0.40; 'your': 0.61; 'cost': 0.65; 'premature': 0.84; 'sender:addr:chris': 0.84; 'url:rebertia': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rebertia.com; s=google; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=yg54yD1dVYGYH7T5L2TmKPUbTy4Td/4b48ebUX9y1Vw=; b=NQH7O+HvFYh5FpHnJM4sfhszAc/phYtJXEx2IhKJ1Po45iJhvUK+fSMkmt304v+10S p9I98t2dH9dYHJ0dQijz5hdf8yCwBwrCxdfG90m6DlnUN7SWsvcyGFnsgTpdOo2FN/LS JsnD1/wZtNp05aF5N4CqSJOtGWuQx6DGzgwqA= MIME-Version: 1.0 Sender: chris@rebertia.com In-Reply-To: <52c256ae-81b0-4a7c-9047-42e1ae8b6eda@n19g2000prh.googlegroups.com> References: <52c256ae-81b0-4a7c-9047-42e1ae8b6eda@n19g2000prh.googlegroups.com> Date: Sat, 10 Sep 2011 00:40:51 -0700 X-Google-Sender-Auth: gx2JwxC84Pq8Yh9D8-KzZNMhHU0 Subject: Re: Applying a function recursively From: Chris Rebert To: hetchkay Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Cc: python-list@python.org X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 55 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1315640455 news.xs4all.nl 2534 [2001:888:2000:d::a6]:46546 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:13053 On Sat, Sep 10, 2011 at 12:19 AM, hetchkay 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): > =C2=A0 if isinstance(obj, MyType): > =C2=A0 =C2=A0 =C2=A0return func(obj) > =C2=A0 elif isinstance(obj, dict): > =C2=A0 =C2=A0 =C2=A0return dict((convert(key, func), convert(value, func)= ) for key, > value in obj.iteritems()) > =C2=A0 elif isinstance(obj, (list, tuple, set)): > =C2=A0 =C2=A0 =C2=A0return obj.__class__(convert(x, func) for x in obj) > =C2=A0 else: > =C2=A0 =C2=A0 =C2=A0return 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 =3D {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