1

This question is related to: Python Counter Comparison as Bag-type

In Python 3, comparing two counters will result in a "TypeError: unorderable types:Counter() > Counter()".

For sets in Python, we can do things like: set1 < set2, set1 <= set2; if we treat yje Counter type as multiset, then why such comparisons are not built in the collections module? Is there any design document/PEP proposal specifying any reasons for not building in such comparisons for the Counter/multiset type in Python 3 (that is, removing such comparators from Python 2 to Python 3)?

charlesqwu
  • 354
  • 2
  • 11
  • 2
    Subset/superset comparisons are easy to do with Counters anyway. For instance, to check if `c1` is a subset of `c2` you could do something like `not c1-c2` or `all(c2[x] >= c1[x] for x in c1)`. – miradulo Aug 07 '17 at 23:01

2 Answers2

1

Counters aren't sets, they're dicts. You can't compare dicts either:

>>> {1:1,2:2} < {1:1,2:2,3:3}
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    {1:1,2:2}<{1:1,2:2,3:3}
TypeError: unorderable types: dict() < dict()
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Hi Mark, Thanks for your answer/comment. Actually, as I mentioned in my question, in Python 2.7, comparison between two dicts in general, and between two counters in particular, is possible; but now in Python 3.X, such comparisons will generate TypeError. My question is: What is the logic/reason for this change from Python 2.7 to Python 3.X? – charlesqwu Aug 09 '17 at 17:07
  • @charlesqwu in general the rules for comparing objects in Python 3 are much more restrictive that the rules in Python 2. I can't find anything about dicts specifically though. I suspect it was just because it's difficult to define a useful rule for when one dict would be less than another. – Mark Ransom Aug 09 '17 at 17:25
0

Unfortunately, you're right - Python's collections.Counter does not implement the subset operators <, <=, >, >= like set does, although it could easily have implemented it. Other multiset implementations in Python like this one do implement it.

But it's fairly easy to implement this yourself. For example, here is a function checking c1 <= c2 (c1 is a subset of c2, or equal):

def is_subset(c1, c2):
    return all(c1[x] <= c2[x] for x in c1)

What this function does it to take at all the element counts in c1, and check that the same element also exists in c2 - and in a larger or equal count.

Nadav Har'El
  • 11,785
  • 1
  • 24
  • 45