Is there a way to set multiple defaults in python python using another dict?

Suppose I have two dicts in Python:

mydict = { 'a': 0 } defaults = { 'a': 5, 'b': 10, 'c': 15 } 

I want to be able to extend mydict using the default values ​​from defaults , so that 'a' remains the same, but 'b' and 'c' are populated. I know about dict.setdefault() and dict.update() , but everyone does only half of what I want - with dict.setdefault() , I have to dict.setdefault() over each variable in defaults ; but with dict.update() , defaults will blow away any pre-existing values ​​in mydict .

Is there some kind of functionality that I don't find built in to Python that can do this? And if not, is there a more pythonic way to write a loop to re-call dict.setdefaults() than this:

 for key in defaults.keys(): mydict.setdefault(key, defaults[key]) 

Context: I write some data in Python, which controls how to parse an XML tree. There is a dict for each node (i.e. How to process each node), and I would prefer that the data I write is sparse, but filled by default. The sample code is just an example ... real code has many more key / value pairs in the standard dict.

(I understand that this whole question is just a minor pun, but it bothered me, so I was wondering if there is a better way to do this that I don't know about.)

+7
python dictionary
source share
5 answers

Could you make mydict the default copy. So mydict will have all the correct values ​​to start with?

 mydict = default.copy() 
+7
source share

You can do this in the same way as the Python.DefaultDict collections:

 class MultiDefaultDict(dict): def __init__(self, defaults, **kwargs): self.defaults = defaults self.update(kwargs) def __missing__(self, key): return self.defaults[key] >>> mydict2 = MultiDefaultDict(defaults, a=0) >>> mydict2['a'] 0 >>> mydict2['b'] 10 >>> mydict2 {'a': 0} 

The rest of the solutions posted so far duplicate all the defaults; it separates them as requested. You may or may not want to override other dict methods, such as __contains __ (), __iter __ (), items (), keys (), values ​​() - this class, as defined here, iterates only over elements other than from the default value.

+5
source share

If you don't mind creating a new dictionary in this process, this will do the trick:

 newdict = dict(defaults) newdict.update(mydict) 

Now newdict contains what you need.

+3
source share
 defaults.update(mydict) 
0
source share

Personally, I like to add a dictionary object. It works basically like a dictionary, except that you must first create an object.

 class d_dict(dict): 'Dictionary object with easy defaults.' def __init__(self,defaults={}): self.setdefault(defaults) def setdefault(self,defaults): for key, value in defaults.iteritems(): if not key in self: dict.__setitem__(self,key,value) 

This provides the same functionality as the dict type, except that it overrides the setdefault () method and accepts a dictionary containing one or more elements. You can set default values ​​at creation.

This is only a personal preference. Since I understand that dict.setdefault () does set items that have not yet been set. Probably the easiest option is:

 new_dict = default_dict.copy() new_dict.update({'a':0}) 

However, if you do this more than once, you can make a function out of it. At the moment, it's easier to just use a custom dict object, rather than constantly adding dictionaries by default.

0
source share

All Articles