List of given type

Alex Martelli aleax at aleax.it
Mon Mar 31 04:24:09 EST 2003


Zaur Shibzoukhov wrote:

> "Terry Reedy" wrote:
> 
> TR> You *might* find either the array module or (3rd party) numerical
> TR> Python lib of interest also (if you have not checked them out
> TR> already).
> 
> I know about array module and numerical extensions. But I want another
> thing. I need standard list of objects with a given type:
> list of int, list of float, list of list, list of dict, list of string,
> ... - list of any type.
> 
> My lists aren't large and in this case array module and numerical dosn't
> speedup computation very much.

Then I think your general approach -- trying to turn whatever's being
inserted / appended / itemassigned / sliceassigned / etc etc, into the
target type, is OK.  However, I would refactor out the issue of deciding
how to "turn things into the target type" to a separate callable, as
it really depends on details, and your 'listofX' type has a big job to
ensure it's catching ALL ways to poke items into self (a tad easier with
Python 2.3, since you don't need to worry about _setslice__ any more,
but, that IS a detail;-)...:

class listofX(list):
    def __init__(self, trasf, parm=()):
        self.trasf = trasf
        list.__init__(self.trall(parm))
    def trall(self, seq):
        return [self.trasf(x) for x in seq]
    def __setitem__(self, index, item):
        if isinstance(index, (int,long)):
            list.__setitem__(self,index,self.trasf(item))
        else: # slice assignment, perhaps
            list.__setitem__(self,index,self.trall(item))
    def append(self, item):
        list.append(self, self.trasf(item))
    def insert(self, index, item):
        list.insert(self, index, self.trasf(item))
    def extend(self, seq):
        list.extend(self, self.trall(seq))

I may be forgetting something here, but roughly this seems to be
what you need.  You may also want to override other methods such
as count, index, and __contain__, so that items being checked for
being in the list get transformed AS IF they were about to be
inserted -- otherwise, with the code as just presented, you'd get
some behavior such as:

lo = listofX(str)
lo.append(23)
print lo.count(23)

printing 0 even though you just appended that 23 (but what got
appended was transformed into a str -- so the == check implicitly
done by lo.count isn't succeeding...).

For many target types you may just pass the target type itself
as the 'trasf' parameter, since calling the type with one of
its instances as the argument works acceptably, and calling it
with an argument of some other type does transformation.  But
you might not want e.g. listofX(list), which appends &c COPIES
of list objects you're appending, so for such issues you'll
want to code and pass in different 'trasf' arguments -- which
is why I think 'trasf' should DEFINITELY be "out of the way",
coded separately and passed in to listofX as an argument, NOT
"rolled into" the listofX code as you had it originally.


But that's really the only change I would suggest.


Alex





More information about the Python-list mailing list