7

I have two dictionaries.

a = {"ab":3, "bd":4}
b = {"cd":3, "ed":5}` 

I want to combine them to {'bd': 4, 'ab': 3, 'ed': 5, 'cd': 3}.

As this says, a.update(b) can complete it. But when I try, I get:

type(a.update(b)) #--> type 'NoneType'

Would anyone like to explain it to me why I cannot gain a dict type?

I also tried this, and it did well:

type(dict(a,**b)) #-->type 'dict'

What is the difference between these two methods and why did the first one not work?

Community
  • 1
  • 1
allenwang
  • 727
  • 2
  • 8
  • 25

3 Answers3

9

The update method updates a dict in-place. It returns None, just like list.extend does. To see the result, look at the dict that you updated.

>>> a = {"ab":3, "bd":4}
>>> b = {"cd":3, "ed":5}
>>> update_result = a.update(b)
>>> print(update_result)
None
>>> print(a)
{'ed': 5, 'ab': 3, 'bd': 4, 'cd': 3}

If you want the result to be a third, separate dictionary, you shouldn't be using update. Use something like dict(a, **b) instead, which, as you've already noticed, constructs a new dict from the two components, rather than updating one of the existing ones.

Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
3

dict.update() returns None, just like most methods that modify a container in place (list.append(), list.sort(), set.add() etc). That's by design so you don't get fooled into thinking it creates a new dict (or list etc).

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
3

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}
Rick
  • 43,029
  • 15
  • 76
  • 119