how can I avoid abusing lists?

Bruno Desthuilliers onurb at xiludom.gro
Fri Jul 7 13:23:55 EDT 2006


Thomas Nelson wrote:
> I have this code:
> type1 = [0]
> type2 = [0]
> type3 = [0]
> map = {0:type1, 1:type1, 2:type3, 3:type1, 4:type2}  

Warning : you're shadowing the builtin map() function.

> # the real map is
> longer than this
> 
> def increment(value):
> 	map[value][0] += 1
> 
> increment(1)
> increment(1)
> increment(0)
> increment(4)
> #increment will actually be called many times through other functions
> print type1[0], type2[0], type3[0]
> #should print "3 1 0"
> 
> This is exactly what I want to do: every time I encounter this kind of
> value in my code, increment the appropriate type by one.  Then I'd like
> to go back and find out how many of each type there were.  This way
> I've written seems simple enough and effective, but it's very ugly and
> I don't think it's the intended use of lists.

Not really.

>  Does anyone know a
> cleaner way to have the same funtionality?


# first replace the list hack
class Counter(object):
    def __init__(self, name, *keys):
        self.name = name
        self.keys = keys
        self.count = 0

    def inc(self):
        self.count += 1

# now wrap the whole thing in a convenient way
class Counters(object):
    def __init__(self, *counters):
        self._counters = dict()
        self._counters_map = dict()
        for counter in counters:
            assert counter.name not in self._counters
            self._counters[counter.name] = counter
            for key in counter.keys:
                assert key not in self._counters_map
                self._counters_map[key] = counter

    def __getattr__(self, name):
        return self._counters[name].count

    def __getitem__(self, key):
        return self._counters_map[key].count

    def __call__(self, key):
        self._counters_map[key].inc()

# and finally, let's use it:
increment = Counters(Counter("type1", 0, 1, 3),
                     Counter("type2", 4),
                     Counter("type3", 2)
                     )

increment(1)
increment(1)
increment(0)
increment(4)

print increment.type1, increment.type2, increment.type3


HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list