Style guide for subclassing built-in types?

Nick Coghlan ncoghlan at iinet.net.au
Thu Feb 24 05:00:38 EST 2005


janeaustine50 at hotmail.com wrote:
> Thank you but your advice doesn't fit in my case since I want to keep
> the memory usage and the initial time minimum. iterable[::-1] would
> build another list and it would take big memory and time during
> reversing if iterable were huge. (and the "iterable" wouldn't be
> garbage-collected because I want to keep a reference to it)

1. Do you have benchmark results or a mathematical analysis to show that 
duplicating the list uses too much memory, or is too slow to startup?

2. Do you have quantitative definitions for "too much" and "too slow", and 
rationale to back up those numbers?

3. Do you have a benchmark to determine if attempting to reduce memory 
consumption and start-up time has a detrimental effect on run-time performance?

If the answer to any of the above questions is 'no', then just do something like:

from itertools import islice, chain
def twisted_iter(orig):
     halfway, skip_middle = divmod(len(orig), 2)
     fwditr = islice(iter(orig), halfway + skip_middle, None)
     revitr = islice(reversed(orig), halfway, None)
     return chain(revitr, fwditr)

Py> from itertools import islice, chain
Py> def twisted_iter(orig):
...     halfway, skip_middle = divmod(len(orig), 2)
...     fwditr = islice(iter(orig), halfway + skip_middle, None)
...     revitr = islice(reversed(orig), halfway, None)
...     return chain(revitr, fwditr)
...
Py> list(twisted_iter(range(10)))
[4, 3, 2, 1, 0, 5, 6, 7, 8, 9]
Py> list(twisted_iter(range(11)))
[5, 4, 3, 2, 1, 0, 6, 7, 8, 9, 10]

Since twisted_iter is actually a highly-optimised twisted view of the original 
list, you may want to just leave the original list alone, and create 
twisted_iter's when you want them.

However, if you mainly use the twisted view, and only occasionally want the 
original view, then you can twist it once, store the result, discard the 
original, and twist it again to get the original back:

Py> list(twistediter(list(twistediter(range(10)))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Py> list(twistediter(list(twistediter(range(11)))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Those benchmarks I mentioned earlier will let you know which approach is best.

No-optimisations-without-measurements-'ly,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list