TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

Question:

I try to sum two dictionaries like that:

my_new_dict = dict(my_existing_dict.items() + my_new_dict.items())

but recieve error

TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

What I do wrong?

Asked By: JohnDow

||

Answers:

As of Python 3.9 (PEP 584 in particular), dicts gains union (|) and update (|=) operations just like sets, so that becomes the "one true way" to achieve what you are looking for.

d1 | d2

That PEP lists the other options available in earlier Python versions, which all have their downsides. If you are up to PEP 448 (Python 3.5), I would recommend using:

{**d1, **d2}

This is unpacking both dictionaries into a new one, resulting in a union.

One problem is the behavior you want is ambiguous – dictionaries can’t have duplicate keys, so it is unclear what you want to happen if both contain the same key. The spec is explicit about what should happen when using this method:

In dictionaries, later values will always override earlier ones

If you want the reverse behaviour, you can simply swap the order of the dictionaries in the literal.

Your approach doesn’t work because dictionary views are set-like, so they don’t have addition implemented.

What you probably want is the union: d1.items() | d2.items(), which will give you a set of tuples of (key, value). If you then pass it to dict() and there are duplicates, the "last" value will be the one used, however sets (unlike the views themselves) are unordered, so there is no guarantee about which item will end up "first" in the combined set, meaning that which one "wins" will be arbitrary.

So, in short, as long as order/duplicate selection isn’t important:

dict(d1.items() | d2.items())

In Python 2, dict.items() simply returns a list, where your approach will work.

Answered By: Gareth Latty

In python3, dict.items() returns an object with type dict_items which apparently can’t be added. (in python 2, it returned a list which could be added).

An alternative way to add a pair of dictionaries which works on py2k and py3k:

d = dict1.copy()
d.update(dict2)

Of course, there’s some ambiguity about what you want to happen in the case of key collisions. e.g. if both dicts have key1, whose key1 should be preserved in the output? Or should you use some combination of both of their values? In the latter case, you’ll probably want something from the collections module (either defaultdict or Counter)

Answered By: mgilson

Another approach to the other suggested answers is:

dict(list(d1.items()) + list(d2.items()))

If there are keys present in both d1 and d2, the value in d2 will be used in the final dictionary.

Answered By: erwaman
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.