How to copy a dict and modify it in one line of code
Solution
Build a function for that.
Your intention would be clearer when you use it in the code, and you can handle complicated decisions (e.g., deep versus shallow copy) in a single place.
def copy_dict(source_dict, diffs):
"""Returns a copy of source_dict, updated with the new key-value
pairs in diffs."""
result=dict(source_dict) # Shallow copy, see addendum below
result.update(diffs)
return result
And now the copy is atomic, assuming no threads involved:
setup2=copy_dict(setup1, {'param1': val10, 'param2': val20})
Addendum - deep copy
For primitives (integers and strings), there is no need for deep copy:
>>> d1={1:'s', 2:'g', 3:'c'}
>>> d2=dict(d1)
>>> d1[1]='a'
>>> d1
{1: 'a', 2: 'g', 3: 'c'}
>>> d2
{1: 's', 2: 'g', 3: 'c'}
If you need a deep copy, use the copy
module:
result=copy.deepcopy(source_dict) # Deep copy
instead of:
result=dict(setup1) # Shallow copy
Make sure all the objects in your dictionary supports deep copy (any object that can be pickled
should do).
setup2 = dict(setup1.items() + {'param1': val10, 'param2': val20}.items())
This way if new keys do not exist in setup1
they get added, otherwise they replace the old key/value pairs.
The simplest way in my opinion is something like this:
new_dict = {**old_dict, 'changed_val': value, **other_new_vals_as_dict}
You could use keyword arguments in the dictionary constructor for your updates
new = dict(old, a=1, b=2, c=3)
# You can also unpack your modifications
new = dict(old, **mods)
This is equivalent to:
new = old.copy()
new.update({"a": 1, "b": 2, "c": 3})
Source
Notes
dict.copy()
creates a shallow copy.- All keys need to be strings since they are passed as keyword arguments.