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.
精彩评论