[Python-Dev] Counter proposal: multidict (was: Proposal: defaultdict) (original) (raw)
Ian Bicking ianb at colorstudy.com
Fri Feb 17 20:51:04 CET 2006
- Previous message: [Python-Dev] Proposal: defaultdict
- Next message: [Python-Dev] Counter proposal: multidict (was: Proposal: defaultdict)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message: [Python-Dev] Proposal: defaultdict
- Next message: [Python-Dev] Counter proposal: multidict (was: Proposal: defaultdict)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]