[Python-Dev] Counter proposal: multidict (was: Proposal: defaultdict)

Ian Bicking ianb at colorstudy.com
Fri Feb 17 20:51:04 CET 2006


I really don't like that defaultdict (or a dict extension) means that 
x[not_found] will have noticeable side effects. This all seems to be a 
roundabout way to address one important use case of a dictionary with 
multiple values for each key, and in the process breaking an important 
quality of good Python code, that attribute and getitem access not have 
noticeable side effects.
So, here's a proposed interface for a new multidict object, borrowing 
some methods from Set but mostly from dict. Some things that seemed 
particularly questionable to me are marked with ??.
class multidict:
 def __init__([mapping], [**kwargs]):
 """
 Create a multidict:
 multidict() -> new empty multidict
 multidict(mapping) -> equivalent to:
 ob = multidict()
 ob.update(mapping)
 multidict(**kwargs) -> equivalent to:
 ob = multidict()
 ob.update(kwargs)
 """
 def __contains__(key):
 """
 True if ``self[key]`` is true
 """
 def __getitem__(key):
 """
 Returns a list of items associated with the given key. If
 nothing, then the empty list.
 ??: Is the list mutable, and to what effect?
 """
 def __delitem__(key):
 """
 Removes any instances of key from the dictionary. Does
 not raise an error if there are no values associated.
 ??: Should this raise a KeyError sometimes?
 """
 def __setitem__(key, value):
 """
 Same as:
 del self[key]
 self.add(key, value)
 """
 def get(key, default=[]):
 """
 Returns a list of items associated with the given key,
 or if that list would be empty it returns default
 """
 def getfirst(key, default=None):
 """
 Equivalent to:
 if key in self:
 return self[key][0]
 else:
 return default
 """
 def add(key, value):
 """
 Adds the value with the given key, so that
 self[key][-1] == value
 """
 def remove(key, value):
 """
 Remove (key, value) from the mapping (raising KeyError if not
 present).
 """
 def discard(key, value):
 """
 Remove like self.remove(key, value), except do not raise
 KeyError if missing.
 """
 def pop(key):
 """
 Removes key and returns the value; returns [] and does nothing
 if the key is not found.
 """
 def keys():
 """
 Returns all the keys which have some associated value.
 """
 def items():
 """
 Returns [(key, value)] for every key/value pair. Keys that
 have multiple values will be returned as multiple (key, value)
 tuples.
 """
 def __len__():
 """
 Equivalent to len(self.items())
 ??: Not len(self.keys())?
 """
 def update(E, **kwargs):
 """
 if E has iteritems then::
 for k, v in E.iteritems():
 self.add(k, v)
 elif E has keys:
 for k in E:
 self.add(k, E[k])
 else:
 for k, v in E:
 self.add(k, v)
 ??: Should **kwargs be allowed? If so, should it the values
 be sequences?
 """
 # iteritems, iterkeys, iter, has_key, copy, popitem, values, clear
 # with obvious implementations


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /