[Python-Dev] dict.addlist()
Guido van Rossum
guido at python.org
Tue Jan 20 10:34:53 EST 2004
> Here is anidea to kick around:
>
> Evolve and eventually replace dict.setdefault with a more specialized
> method that is clearer, cleaner, easier to use, and faster.
>
> d.addlist(k, v) would work like d.setdefault(k, []).append(v)
>
>
> Raymond Hettinger
>
>
> >>> d = dict()
> >>> for elem in 'apple orange ant otter banana asp onyx boa'.split():
> ... k = elem[0]
> ... d.addlist(k, elem)
> ...
> >>> d
> {'a': ['apple', 'ant', 'asp'], 'b': ['banana', 'boa'], 'o': ['orange',
> 'otter',
> 'onyx']}
>
>
> bookindex = dict()
(What's wrong with {}?)
> for pageno, page in enumerate(pages):
> for word in page:
> bookindex.addlist(word, pageno)
I'm -0 on the idea (where does it stop? when we have reimplemented
Perl?), and -1 on the name (it suggests adding a list).
It *is* a somewhat common idiom, but do we really need to turn all
idioms into method calls? I think not -- only if the idiom is hard to
read in its natural form.
bookindex = {}
for pageno, page in enumerate(pages):
for word in page:
lst = bookindex.get(word)
if lst is None:
bookindex[word] = lst = []
lst.append(pageno)
works for me. (I think setdefault() was already a minor mistake -- by
the time I've realized it applies I have already written working code
without it. And when using setdefault() I always worry about the
waste of the new empty list passed in each time that's ignored most
times.)
If you really want library support for this idiom, I'd propose adding
a higher-level abstraction that represents an index:
bookindex = Index()
for pageno, page in enumerate(pages):
for word in page:
bookindex.add(word, pageno)
What you're really doing here is inverting an index; maybe that idea
can be leveraged?
bookindex = Index()
bookindex.fill(enumerate(pages), lambda page: iter(page))
This would require something like
class Index:
def __init__(self):
self.map = {}
def fill(self, items, extract):
for key, subsequence in items:
for value in extract(subsequence):
self.map.setdefault(value, []).append(key)
Hm, maybe it should take a key function instead:
bookindex = Index()
bookindex.fill(enumerate(pages), lambda x: iter(x[1]), lambda x:
x[0])
with a definition of
class Index:
def __init__(self):
self.map = {}
def fill(self, seq, getitems, getkey):
for item in seq:
key = getkey(item)
for value in getitems(item):
self.map.setdefault(value, []).append(key)
Hmm... Needs more work... I don't like using extractor functions.
But I like addlist() even less.
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list