A small proposed change to dictionaries' "get" method
Alex Martelli
alex at magenta.com
Thu Aug 3 05:08:21 EDT 2000
"Gareth McCaughan" <Gareth.McCaughan at pobox.com> wrote in message
news:slrn8oh81f.1m8e.Gareth.McCaughan at g.local...
[snip]
> existing_lines = word2lines.get(word, []) |
> existing_lines.append(line_number) | ugh!
> word2lines[word] = existing_lines |
[snip]
> All very simple and elegant. There's just one wart: the
> three lines I've labelled "ugh!" seem much more verbose
> and inefficient than they should be. We have to search
> word2lines twice for "word" (once to see if it's there,
Agreed. As a stylistic issue, I'd probably code it as:
try:
word2lines[word].append(line_number)
except KeyError:
word2lines[word]=[line_number]
Yeah, I know, that's 4 lines instead of 3:-). But it looks
more natural to me -- the mainstream being to append
one more line number, the exceptional case to create
a new list with just the current line-number in it. Eye of
the beholder, no doubt.
> This (update a mutable object that's a value in a dictionary,
> initialising it first if appropriate) is a common idiom, at
> least in my programs. It's a shame that it should be so ugly.
Yes, I use it often, too. Good point.
> I suggest a minor change: another optional argument to
> "get" so that
>
> dict.get(item,default,flag)
>
> is equivalent to
>
> if dict.has_key(item):
> VALUE IS dict[item]
> else:
> if flag: dict[item] = default <-- This is all that's new
> VALUE IS default
Nice, except I wouldn't call it 'get' and distinguish it from the
normal case with an extra optional flag, but rather give it
another name (hard to find a good one without more thought,
but it should give a hint that it can mutate the dict; maybe
mutatingGet, but that seems far too verbose...).
Of course, it doesn't really have to be a member of dict
(of course you can make it one through UserDict):
def myget(dict, item, default):
if not dict.has_key(item):
dict[item]=default
return dict[item]
I realize that calling myget(dict,item,default) is not as
syntactically neat as calling dict.myget(item,default),
but it's not really too bad, is it? Of course, having it as
a member would likely be slightly more efficient as
well as syntactically neater. And I do believe the need
is widespread enough -- maybe as high as for the non
mutating variant of get we now have. C++ automagically
adds keys to a std::map when they're referred to through
operator[], and, just for once, it may be more convenient
than Python in this one regard!-)
Alex
More information about the Python-list
mailing list