How to copy a dict and modify it in one line of code

后端 未结 9 945
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-29 00:50

Very often I need to create dicts that differ one from another by an item or two. Here is what I usually do:

setup1 = {\'param1\': val1, 
            \'param         


        
相关标签:
9条回答
  • 2020-12-29 01:24

    You can write your own class using UserDict wrapper, and simply add dicts like

    # setup1 is of Dict type (see below)
    setup2 = setup1 + {'param1': val10}
    

    All you have to do is

    • Define a new class using UserDict as base class
    • Implement __add__ method for it.

    Something like :

    class Dict(dict):
        def __add__(self, _dict):
            if isinstance(_dict, dict):
                tmpdict = Dict(self)
                tmpdict.update(_dict)
                return tmpdict
    
            else:
                raise TypeError
    
        def __radd__(self, _dict):
             return Dict.__add__(self, _dict)
    0 讨论(0)
  • 2020-12-29 01:26

    The simplest way in my opinion is something like this:

    new_dict = {**old_dict, 'changed_val': value, **other_new_vals_as_dict}
    
    0 讨论(0)
  • 2020-12-29 01:28

    I like this line (after from itertools import chain):

    d3 = dict(chain(d1.items(), d2.items()))
    

    (Thanks for juanpa.arrivillaga for the improvement!)

    0 讨论(0)
  • 2020-12-29 01:31

    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.
    0 讨论(0)
  • 2020-12-29 01:33

    This is an extension to the nice answer posted by Adam Matan:

    def copy_dict(d, diffs={}, **kwargs):
        res = dict(d)
        res.update(diffs)
        res.update(kwargs)
        return res
    

    The only difference is the addition of kwargs. Now one can write

    setup2 = copy_dict(setup1, {'param1': val10, 'param2': val20})
    

    or

    setup2 = copy_dict(setup1, param1=val10, param2=val20)
    
    0 讨论(0)
  • 2020-12-29 01:37
    setup2 = dict((k, {'param1': val10, 'param2': val20}.get(k, v))
                  for k, v in setup1.iteritems())
    

    This only works if all keys of the update dictionary are already contained in setup1.

    If all your keys are strings, you can also do

    setup2 = dict(setup1, param1=val10, param2=val20)
    
    0 讨论(0)
提交回复
热议问题