[Python-Dev] dict.addlist() (original) (raw)
Guido van Rossum guido at python.org
Tue Jan 20 10:34:53 EST 2004
- Previous message: [Python-Dev] dict.addlist()
- Next message: [Python-Dev] dict.addlist()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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/)
- Previous message: [Python-Dev] dict.addlist()
- Next message: [Python-Dev] dict.addlist()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]