itertools.flatten()? and copying generators/iterators.
Francis Avila
francisgavila at yahoo.com
Wed Oct 29 20:47:54 EST 2003
More information about the Python-list mailing list
Wed Oct 29 20:47:54 EST 2003
- Previous message (by thread): Tweaking flatten() (was: Re: itertools.flatten()? and copying generators/iterators.)
- Next message (by thread): itertools.flatten()? and copying generators/iterators.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
"Peter Otten" <__peter__ at web.de> wrote in message news:bnonsi$l5a$05$1 at news.t-online.com... > > def flatten_dict(s, isScalar): > try: > scalar = isScalar[s.__class__] > except KeyError: ... > t = s.__class__ Why doesn't the above fail (AttributeError) for classic classes? ... > scalar = isScalar[t] = True > else: > scalar = isScalar[t] = False This part I never would have thought to do. Clever! ... > for flatten_dict(). So you get some speed up at the cost of uglier though > still quite readable code and under the assumption that either all or no > instances of a class are iterable. That's not always a good assumption to make, if we want to decide whether to iterate based upon some property of the object (which is actually how I originally discovered I needed a "flatten"). Perhaps we can combine both conditions and caching optimizations? def flatten_fastcond(s, isScalar, itercond=lambda o: None): try: scalar = isScalar[s.__class__] except KeyError: # If itercond has something to say about s, use *it*, and don't # add the lookup to isScalar. iterate = itercond(s) if not iterate is None: scalar = iterate if not scalar: s = iter(s) else: t = s.__class__ try: s = iter(s) except TypeError: scalar = isScalar[t] = True else: scalar = isScalar[t] = False if scalar: yield s else: for elem in s: for subelem in flatten_dict(elem, isScalar): yield subelem It's usually true that all instances of a given class are iterable or not, and it's less inconvenient to add an entry to a dictionary than to write a conditional test (also faster). If we move the itercond block above 'try', we'll slow down this more common case, but speed things up if s is a homogenous structure where itercond does all the work of deciding. There are probably other things I could say against it if I thought about it, and we're fast enough anyway. As expected, given the same test tree (which doesn't exercise itercond), the speed is about the same. >python timeit.py -c -s"import flatten" "flatten.pro_fastcond()" 100 loops, best of 3: 6.29e+003 usec per loop >python timeit.py -c -s"import flatten" "flatten.pro_dict()" 100 loops, best of 3: 6.29e+003 usec per loop I'll make up some fancy tree later to test out itercond. -- Francis Avila
- Previous message (by thread): Tweaking flatten() (was: Re: itertools.flatten()? and copying generators/iterators.)
- Next message (by thread): itertools.flatten()? and copying generators/iterators.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list