Add two dicts

Alex Martelli aleax at aleax.it
Fri Aug 29 04:40:01 EDT 2003


Afanasiy wrote:

> On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis <max at alcyone.com>
> wrote:
> 
>>Afanasiy wrote:
>>
>>> Can I add two dicts in a way which is not cumbersome to the above %
>>> string
>>> operation? Is this another case of writing my own function, or does a
>>> builtin (or similar) already exist for this?
>>
>>combinedDict = aDict.copy()
>>combinedDict.update(anotherDict)
>>
>>If that's cumbersome, don't really know what you'd consider
>>non-cumbersome.
> 
> Don't really know if you're asking, but :
> 
>   vars(self)+{'x':'123','y':'345'}
> 
> I would consider that non-cumbersome. ;-)

So, what about:

def dict_add(adict, another):
    result = adict.copy()
    result.update(another)
    return result

and then dict_add(vars(self),  {'x':'123','y':'345'}) ?  But in fact
you can do even better...:

def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(_another)
    result.update(_yetmore)
    return result

or in 2.3:

def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(dict(_another, **_yetmore))
    return result


and now, dad(vars(self), x='123', y='345') -- ain't that even
LESS cumbersome?  You can't do that with the syntax of + (no
keyword arguments)

Incidentally, in 2.3 you can ALSO spell your desired
    adict+anotherdict
as
    dict(adict, **anotherdict)

> My only guess why that doesn't exist is that no one decided what to do on
> like keys. Use existing, overwrite, or throw exception (my preference).

The semantics of all the existing ways of spelling dictionary addition
and the like (update method, **kwds argument to dict in 2.3) have the
second argument 'override' the first.  A fast way to check that two
dicts don't overlap (or perhaps more generally to get the list of the
keys in which they do overlap) might be more generally useful, as well
as allowing the diagnostics you want to be produced effectively.  Still,
as long as you're writing a function for the addition it's easy and
fast to check for non-overlap:

def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(dict(_another, **_yetmore))
    if len(result)!=len(_adict)+len(_another)+len(_yetmore):
        raise ValueError, "Overlapping keys on dict addition"
    return result


Alex





More information about the Python-list mailing list