Why doesn't a python dict.update() return the object?
Python's mostly implementing a pragmatically tinged flavor of command-query separation: mutators return None
(with pragmatically induced exceptions such as pop
;-) so they can't possibly be confused with accessors (and in the same vein, assignment is not an expression, the statement-expression separation is there, and so forth).
That doesn't mean there aren't a lot of ways to merge things up when you really want, e.g., dict(a, **award_dict)
makes a new dict much like the one you appear to wish .update
returned -- so why not use THAT if you really feel it's important?
Edit: btw, no need, in your specific case, to create a
along the way, either:
dict(name=name, description=desc % count, points=points, parent_award=parent,
**award_dict)
creates a single dict with exactly the same semantics as your a.update(award_dict)
(including, in case of conflicts, the fact that entries in award_dict
override those you're giving explicitly; to get the other semantics, i.e., to have explicit entries "winning" such conflicts, pass award_dict
as the sole positional arg, before the keyword ones, and bereft of the **
form -- dict(award_dict, name=name
etc etc).
Python's API, by convention, distinguishes between procedures and functions. Functions compute new values out of their parameters (including any target object); procedures modify objects and don't return anything (i.e. they return None). So procedures have side effects, functions don't. update is a procedure, hence it doesn't return a value.
The motivation for doing it that way is that otherwise, you may get undesirable side effects. Consider
bar = foo.reverse()
If reverse (which reverses the list in-place) would also return the list, users may think that reverse returns a new list which gets assigned to bar, and never notice that foo also gets modified. By making reverse return None, they immediately recognize that bar is not the result of the reversal, and will look more close what the effect of reverse is.
This is easy as:
(lambda d: d.update(dict2) or d)(d1)
Or, if it is important not to modify the dictionary:
(lambda d: d.update(dict2) or d)(d1.copy())
not enough reputation for comment left on top answer
@beardc this doesn't seem to be CPython thing. PyPy gives me "TypeError: keywords must be strings"
The solution with **kwargs
only works because the dictionary to be merged only has keys of type string.
i.e.
>>> dict({1:2}, **{3:4})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings
vs
>>> dict({1:2}, **{'3':4})
{1: 2, '3': 4}