[Python-ideas] Joining dicts again

Steven D'Aprano steve at pearwood.info
Sun Feb 23 15:20:53 CET 2014


On Sun, Feb 23, 2014 at 02:31:27PM +0100, haael at interia.pl wrote:

> @Mathias Panzenböck
> 
> > I never had a case where this kind of conflict resolution made sense. Can
> > you show us an example?
[...]
> Now consider the following:
> 
> Let's have a dict with some function's default parameters:
> {'a':None, 'b':[]}

Seems a bit contrived, but okay.


> Now let's have two separate code blocks that fill those arguments with some computed values.
> 
> def funA(p):
>  p['a'] = 1
>  return p
> 
> def funB(p):
>  p[b] = [1, 2, 3]
>  return p

I notice that both of these mutate the dictionary in place. This is 
important later on.


> Again, this pattern is not uncommon in the programming practice. We
> often have some code blocks that try to fill as much parameters as 
> possible, but not every of them.

I can't say that I've ever done this, but let's continue.

> Finally, we want to merge the dicts returned by these functions and 
> provide them to the function of our interest.
> 
> Basically, we want something like that:
> 
> dict_default = {'a':None, 'b':[]}
> dict_a = funA(dict_default.copy())
> dict_b = funB(dict_default.copy())
> dict_param = merge_using_or_resolution(dict_a, dict_b)
> fun(**dict_param)

I see that you are making dict_a and dict_b mutated copies. I don't 
understand why you don't just work with a single dict, instead of making 
copies all over the place. And since both funA and funB return the 
dict, you can chain them. This is so such simpler than the way you wrote 
it, and avoids all the unnecessary copying:

dict_param = {'a':None, 'b':[]}
fun(**(funA(funB(dict_param))))

Even if you decide that you want to keep the defaults untouched 
(in case you need them later), that makes only a single copy:

dict_defaults = {'a':None, 'b':[]}
fun(**(funA(funB(dict_defaults.copy()))))



-- 
Steven


More information about the Python-ideas mailing list