Update a dictionary with another dictionary, but only non-None values

Question:

From the python documentation I see that dict has an update(...) method, but it appears it does not take exceptions where I may not want to update the old dictionary with a new value. For instance, when the value is None.

This is what I currently do:

for key in new_dict.keys():
  new_value = new_dict.get(key)
  if new_value: old_dict[key] = new_value

Is there a better way to update the old dictionary using the new dictionary.

Asked By: Vaibhav Bajpai

||

Answers:

You could use something like:

old = {1: 'one', 2: 'two'}
new = {1: 'newone', 2: None, 3: 'new'}

old.update( (k,v) for k,v in new.items() if v is not None)

# {1: 'newone', 2: 'two', 3: 'new'}
Answered By: Jon Clements

Update: I think I was trying to answer the wrong question here (see my comment below), since this clearly does not answer the question being asked. In case there is something useful, I’ll leave this here anyway (unless someone makes it clear that it would be better to just delete it).

Building on Jon’s answer but using set intersection as suggested here:

In python 3:

old.update((k, new[k]) for k in old.keys() & new.keys())

In python 2.7:

old.update((k, new[k]) for k in old.viewkeys() & new.viewkeys())

In python 2.7 or 3 using the future package:

from future.utils import viewkeys
old.update((k, new[k]) for k in viewkeys(old) & viewkeys(new))

Or in python 2 or 3 by without the future package by creating new sets:

old.update((k, new[k]) for k in set(old.keys()) & set(new.keys()))
Answered By: teichert

For python 3.x to iterate throughout dictionary key values use for k,v in new.items()

IN: 
old = {1: 'one', 2: 'two'}
new = {1: 'new_one', 2: None, 3: 'new_three'}

old.update((k,v) for k,v in new.items() if v is not None)

Out:
old = {1: 'new_one', 2: 'two'}
Answered By: Aidar Gatin

If you get here from a pydantic object that you created into dict, this wont work. Instead use pydantic function dict(exclude_none). Python 3.7+ For example,

     existing_job = db.query(MedicalRecord).filter(MedicalRecord.id == id)
else:
    existing_job = db.query(MedicalRecord).filter(MedicalRecord.id == id, MedicalRecord.owner_id==user.id)
if not existing_job.first():
    return 0
job.directory_hash = None



#doesnt work:
existing_job.update((k,v) for k,v in job.dict().items() if v is not None)
job = job.dict(exclude_none=True)
existing_job.update(job) # works
Answered By: Salman Marvasti
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.