[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