dictionary question

Jason Orendorff jason at jorendorff.com
Wed Dec 5 13:51:45 EST 2001


=?gb2312?B?1cXJ2bPb?= <zhangsc at neusoft.com> wrote:
> Hello!
>   I have a question about python's dictionary,I have a dictionary 
> type variable, such as 
> dbs={'xk.dhs.org': '166.111.177.77', 
> 'www.symantec.com':'202.112.237.39', 'ftp.happynet.org':'166.111.160.7'}
> When I input dbs['www.symantec.com']='202.112.237.15',I want to 
> get the result like that:
> dbs={'xk.dhs.org': '166.111.177.77', 
> 'www.symantec.com':['202.112.237.39','202.112.237.15'],'ftp.happyn
> et.org':'166.111.160.7'}
> How to realize this function?

Python's built-in dictionary doesn't behave this way.  But you could
write your own dictionary that does this.

In particular, if you have Python 2.2b2 (the very latest), you can
just write a subclass of dict:

class multidict(dict):
    def __setitem__(self, key, value):
        if self.has_key(key):
            existing = self[key]
            if isinstance(existing, list):
                existing.append(value)
            else:
                dict.__setitem__(self, key, [existing, value])
        else:
            dict.__setitem__(self, key, value)

This changes the behavior of __setitem__ in the way you want.
Try it out:

x = multidict()
x['alarmist.org'] = '199.93.70.6'
x['jorendorff.com'] = '208.177.33.252'
x['yahoo.com'] = '64.58.76.223'
x['yahoo.com'] = '64.58.76.229'
x['yahoo.com'] = '64.58.76.177'
print x


> When I input dbs['www.symantec.com']='202.112.237.39',how to 
> determine if this item has exists in dbs,if item has existed, the 
> result is still like this:  [...snip...]
> if item doesn't exist,then insert new value into dbs,How to 
> realize this function?

It's a minor tweak to the above code.  Instead of this...
    existing.append(value)

you'll want to write this...
    if value not in existing:
        existing.append(value)


> When I print dbs,I like the result as follows:  
> 'xk.dhs.org': '166.111.177.77'
> 'www.symantec.com':'202.112.237.39'
> 'www.symantec.com':'202.112.237.15'
> 'ftp.happynet.org':'166.111.160.7'
>  How to realize these function?

Override __str__().  I suggest something like this...

class multidict(dict):

    ... same as above ...
    ... but add these methods ...

    def iteritems(self):
        for k, v in dict.iteritems(self):
            if isinstance(v, list):
                for item in v:
                    yield k, item
            else:
                yield k, v

    def items(self):
        return list(self.iteritems())

    def __str__(self):
        pieces = ["%r: %r" % item for item in self.iteritems()]
        data = ', '.join(pieces)
        return "{%s}" % data

To really flesh out the class, you'll eventually want to
override itervalues(), values(), popitem(), update(), and
maybe a few more.

If you're using an older version of Python, check out the UserDict
module.

-- 
Jason Orendorff
http://www.jorendorff.com/





More information about the Python-list mailing list