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.
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'}
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()))
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'}
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
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.
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'}
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()))
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'}
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