enhancing dictionary update method and the dict type constructor
Tim Peters
tim.one at home.com
Sat Nov 17 15:09:38 EST 2001
[Alexis Layton]
> This message proposes two minor enhancements. Since I've missed the
> feature freeze for Python 2.2, this would be for the next version.
>
> The first enhacement improves the definition of the dictionary "update"
> method, the second enhancement broadens the dictionary type constructor.
>
> In Python 2.2, the new dictionary type factory function "dict"
> (previously known as "dictionary" in 2.2b1) takes either a mapping
> object or a sequence of key, value pairs as its argument.
>
> I would like to propose that the dictionary method "update" be broadened
> to take a similar argument type.
Sorry, Guido already rejected this idea (proposed by me) in a PythonLabs mtg
a few weeks ago. Your hypothetical
adict.update(pairs)
can be spelled
adict.update(dict(pairs))
in 2.2. I agree with the rejection: it's marginally cool for the factory
constructor to convert from different representations, but there was no
intent that sequence-of-pairs be a generally accepted alternative
representation for dicts (kinda similarly, 24 + int("42") works but not 24 +
"42" -- Python is conservative about magical conversions).
> In addition, I believe it would be generally useful if the sequence
> form allowed singleton sequences to represent keys that should be
> omitted from the dictionary, thus:
>
> d = {'a': 1, 'b': 2}
> d.update([('a',), ('b', 0), ('c', 3)])
> print d
> {'c': 3, 'b': 0}
Since d.update(pairs) is dead on arrival, enhancements to it probably don't
stand a better chance <wink>. I especially squirm at this one, since, e.g.,
it would mean that
d.update("oops")
deletes the keys "o", "p" and "s" from d ("oops" is a sequence of
1-sequences), and that's way too obscure.
> I propose that non-existant keys specified in such an update sequence be
> silently ignored.
>
> Given such an expansion of update, it seems to me the more useful
> constructor for dictionaries would be something more akin to:
>
> def dict(*mss):
> d = { }
> for map_or_sequence in mss:
> d.update(map_or_sequence)
> return d
>
> This permits several useful idioms, such as the common case in
> environment binding where a dictionary represents a symbol table and one
> must construct a subsidiary dictionary in which one binding has changed:
>
> d2 = dict(d, ('v', 3))
d2 = d.copy()
d['v'] = 3
> It also permits the "union" of two or more dictionaries: dict(d1, d2).
d = d1.copy()
d.update(d2)
> ASIDE: what is the proper term for this, since keys in d2 can override
> those in d1?
"update", as in d.update(). The Python C API is a little richer:
PyDict_Update actually calls PyDict_Merge with an "override" flag;
PyDict_Merge can be told to let the keys of either input dict "win".
> Finally, for years I've had a little utility function (called "dict" by
> the way) which constructs dictionaries in which all the keys are
> identifiers anyway using the keyword syntax:
>
> def dict(**kw): return kw
>
> The reason is mostly to pre-load certain stupid little look-up tables
> using a more convenient syntax: dict(a=1, b=2, c=3), etc.
Yes, it's a pleasant technique. The good news is that, except for the name,
it's not being taken away.
> The type constructor could also have a **kw behavior which is the final
> update into the new dictionary, as if dict was defined to be:
>
> def dict(*mss, **kw):
> d = { }
> for ms in mss:
> d.update(ms)
> d.update(kw)
> return d
At this point I would despair of explaining what the dict() function does,
and it's not our goal to build in all possible 3-line functions <wink>.
There have been about a dozen other ideas for extending the dict() function
too; adding sequence-of-pairs was our best stab at implementing the most
useful one; most others appear to have an audience of one.
More information about the Python-list
mailing list