Why Doesn't a Python Dict.Update() Return the Object

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).

Why does dict(k=4, z=2).update(dict(l=1)) return None in Python?

The .update() method alters the dictionary in place and returns None. The dictionary itself is altered, no altered dictionary needs to be returned.

Assign the dictionary first:

a_dict = dict(k=4, z=2)
a_dict.update(dict(l=1))
print a_dict

This is clearly documented, see the dict.update() method documentation:

Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.

Why while updating a dictionary getting None?

v.update(b) is updating b in place. v is indeed updated, but the result of the update function is None, exactly what is printed out. If you do something like

v.update(b)
print v

you'll see v (updated)

update method of python dictionary did not work

As a new Python user this was a very frequent "gotcha" for me as I always seemed to forget it.

As you have surmised, a.update(b) returns None, just as a.append(b) would return None for a list. These kinds of methods (list.extend is another) update the data structure in place.

Assuming you don't actually want a to be modified, try this:

c = dict(a)  # copy a
c.update(b) # update a using b
type(c) #returns a dict

That should do it.

Another other way of doing it, which is shorter:

c = dict(a,**b)
type(c) #returns a dict

What is happening here is b is being unpacked. This will only work if the keys of b are all strings, since what you are actually doing is this:

c = dict(a, cd=3, ed=5)
type(c) #returns a dict

Note that for any of the methods above, if any of the keys in a are duplicated in b, the b value will replace the a value, e.g.:

a = {"ab":3, "bd":4}
c = dict(a, ab=5)
c #returns {"ab":5, "bd":4}

Why do we need a dict.update() method in python instead of just assigning the values to the corresponding keys?

1. You can update many keys on the same statement.

my_dict.update(other_dict)

In this case you don't have to know how many keys are in the other_dict. You'll just be sure that all of them will be updated on my_dict.

2. You can use any iterable of key/value pairs with dict.update

As per the documentation you can use another dictionary, kwargs, list of tuples, or even generators that yield tuples of len 2.

3. You can use the update method as an argument for functions that expect a function argument.

Example:

def update_value(key, value, update_function):
update_function([(key, value)])

update_value("k", 3, update_on_the_db) # suppose you have a update_on_the_db function
update_value("k", 3, my_dict.update) # this will update on the dict

Is there a python function to return a new dict with a new key added, like assoc in clojure?

Sure, you can simply use dict(), for example:

old = {"a": 1}
new_one = dict(old, new_key=value)
#or
new_one = dict(old, {...})

Python update a key in dict if it doesn't exist

You do not need to call d.keys(), so

if key not in d:
d[key] = value

is enough. There is no clearer, more readable method.

You could update again with dict.get(), which would return an existing value if the key is already present:

d[key] = d.get(key, value)

but I strongly recommend against this; this is code golfing, hindering maintenance and readability.

Why can I reassign dict.update but not dict.__setitem__

Note that you can define the class __setitem__, e.g.:

def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError('{} has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)

(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)



Related Topics



Leave a reply



Submit