EXOR or symmetric difference for the Counter class
Paddy
paddy3118 at googlemail.com
Tue Aug 17 23:47:55 CEST 2010
On 17 Aug, 02:29, Raymond Hettinger <pyt... at rcn.com> wrote:
> [Paddy]
>
> > Lets say you have two *sets* of integers representing two near-copies
> > of some system, then a measure of their difference could be calculated
> > as:
>
> > len(X.symmetric_difference(Y)) / (len(X) + len(Y)) * 100 %
>
> > If the two collections of integers are allowed duplicates then you
> > need a Counter/bag/multi-set type and the diff calculation I gave
> > originally.
>
> Thanks for sharing your use case.
>
> It's unlikely that I will add this method to the Counter API because
> the rarity of use case does not warrant the added API complexity.
> IMO, adding a method like this makes the class harder to learn,
> understand and remember. It doesn't seem like much of a win over
> using the existing alternatives:
>
> * (b - c) + (c - b)
> * (b | c) - (b & c)
> * DIY using the two counters as simple dicts
> * writing a subclass providing additional binary operations
>
> I would like to see someone post a subclass to the ASPN Cookbook that
> adds a number of interesting, though not common operations. Your
> symmetric_difference() method could be one. A dot_product() operation
> could be another. Elementwise arithmetic is another option (we
> already have add and subtract, but could possibly use multiply,
> divide, etc). Scaling operations are another possibility (multiple
> all elements by five, for example).
>
> The Counter() class has low aspirations. It is a dictionary that
> fills-in missing values with zero and is augmented by a handful of
> basic methods for managing the counts.
>
> Raymond
I created this that could be an addition to the bottom of the Python 3
collections.Counter class definition:
def __xor__(self, other):
''' symmetric difference: Subtract count, but keep only abs
results with non-zero counts.
>>> Counter('abbbc') ^ Counter('bccd')
Counter({'b': 2, 'a': 1, 'c': 1, 'd': 1})
>>> a, b = Counter('abbbc'), Counter('bccd')
>>> (a-b) + (b - a) == a ^ b
True
'''
if not isinstance(other, Counter):
return NotImplemented
result = Counter()
for elem in set(self) | set(other):
newcount = self[elem] - other[elem]
if newcount != 0:
result[elem] = newcount if newcount > 0 else -newcount
return result
- Paddy.
More information about the Python-list
mailing list