[Tutor] indexing with a class

Karl Pflästerer sigurd at 12move.de
Fri Feb 27 21:21:37 EST 2004


On 28 Feb 2004, Christopher Spears <- cspears2002 at yahoo.com wrote:

> I am trying to create a class in the UserDict module
> that will remember the order in which I enter keys. 

If you use a newer Python (newer 2.2 IIRC you can subclass dict()).

> Here is an example of an attempt to solve this
> problem:

> class ODict(UserDict):
>     def __setitem__(self, key, item):
>         counter = 0
>         self.data[key] = item
>         counter = counter + 1
>         self.order = [(key,counter)]

I see here several problems:
(a) you don't show us the __init__ method
(b) above you create always a new list but I think you wanted to append
    the new values to an existing list
(c) the data you give is redundant; counter is implicit in the index of
    the value in the list; so there no need to store it.
(d) With overwriting __setitem__ you solve only a part of the problem
    (hint: try to create a dict with a sequence of tuples (as key, value
    pairs) as input.  You won't find these values in your list.

> The idea was to have the class generate a list of
> tuples that have the key and the order that key was
> entered, i.e. [('key1',1),('key2',2),...etc].

See above what I wrote.

> But when I went for a test run, I got this result
> (UserDict2 is a copy of the UserDict module.  I wanted
> to work with a copy instead of the original for
> safety.):

There's no need for that; you never change an existing module by only
importing it.

[...]
> This has been my first major stumbling block.  When I
> use the class, it keeps overwriting any counters, etc.
> that I use.

Above I wrote why that happens.  Initialice your list as an empty list
(perhaps taking care of the cases when you gave an argument to the
dictionary when you created it) and append() new values.

> Maybe a better way is to pass some sort of result to a
> function under the ODict class?  Right now, I just
> have:

> class ODict(UserDict):
>     def __setitem__(self, key, item):
>         counter = 0
>         self.data[key] = item
>         counter = counter + 1
>         self.order = [(key,counter)]
>     def okeys(self):
>         print order

> This won't work, so my second stumbling block is how
> to do I get this class to pass some sort of useful
> result when I use the __setitem__ special method.  Any hints?

It depends what you regard as useful results?  Do you want to see the
list whenever you entered a new value to the dict?

You could write:

def __setitem__ (self, key, value):
    .
    .
    .
    self.order.append(key)
    return self.order


But the more difficult part is IMO to take care of all the ways you can
create a dict with some values given.

>>> dict(a=1, b=2, c=3)
{'a': 1, 'c': 3, 'b': 2}
>>> dict([('a', 1),('b', 2), ('c', 3)])
{'a': 1, 'c': 3, 'b': 2}
>>> dict({'a':1, 'b':2})
{'a': 1, 'b': 2}

__setitem__ won't get called in any of these cases (at least with
userDict)



   Karl
-- 
Please do *not* send copies of replies to me.
I read the list




More information about the Tutor mailing list