开发者

Python: Adding Dictionary Items.

开发者 https://www.devze.com 2023-01-23 21:46 出处:网络
When we add dictionary Items, we use x.items()+y.items(), but there was something开发者_运维知识库 I don\'t understand.

When we add dictionary Items,

we use x.items()+y.items(), but there was something开发者_运维知识库 I don't understand.

for example

if x={2:2,1:3} and y={1:3,3:1} x.items()+y.items() gives {3:1,2:2,1:3}

so, as you can see, the answer mathematically could have been 6x+2x^2+x^3,

but the dictionary gives x^3+2x^2+3x,

can any one tell me any better method which works better?


Let's be clear what's going on here!

In [7]: x.items()
Out[7]: [(1, 3), (2, 2)]

In [8]: y.items()
Out[8]: [(1, 3), (3, 1)]

In [9]:  x.items() + y.items()
Out[9]: [(1, 3), (2, 2), (1, 3), (3, 1)]

In [10]: dict(x.items() + y.items())
Out[10]: {1: 3, 2: 2, 3: 1}

items() produces a list of (key, value) tuples, and + concatenates the lists. You can then make that list back into a dictionary, which will deal with duplicate keys by taking the last value with a given key. Since it's a duplicate value this time, it doesn't matter, but it could:

In [11]: z = {1:4, 3:1}

In [12]: dict(x.items() + z.items())
Out[12]: {1: 4, 2: 2, 3: 1}

In which case the 1:3 entry is discarded...

(Not clear what your analogy to polynomials is... If you really want to represent polynomials that add arithmetically, you might want to check out the numpy class poly1d or collections.Counter described by @adw.)


When you call dict(x.items()+y.items()), the duplicate keys simply get set twice and the latest set value (the one from y) overwrites the older one (from x).

Since a Python dictionary can have anything as its keys or values (as long as the keys are hashable), how would it know how to combine the old and new value when a key gets replaced?

In Python 2.7 and 3, there is a dictionary subclass called Counter which can only have numbers as values. And when you add two of those together, it does add the values together for duplicate keys:

>>> from collections import Counter
>>> Counter({2:2,1:3}) + Counter({1:3,3:1})
Counter({1: 6, 2: 2, 3: 1})


You could create your own subclass of dict to implement the add operator to do what you wanted:

import copy
class AddingDict(dict):
    def __add__(self, d2):
        new_dict = copy.deepcopy(self)
        for key, value in d2.iteritems():
            if key in new_dict:
                new_dict[key] += value
            else:
                new_dict[key] = value
        return new_dict

And now:

>>> x = AddingDict({2:2,1:3})
>>> y = AddingDict({1:3,3:1})
>>> x+y
{1: 6, 2: 2, 3: 1}

Edit

If you needed extra efficiency, checking if each key is in the new_dict for each key in the original is inefficient, and you could convert each list of keys to a set and take the intersection, but the code would be more complicated and the efficiency is likely not needed. The actual implementation is left as an exercise to the reader.

0

精彩评论

暂无评论...
验证码 换一张
取 消