How to test if a python Counter
is contained in another one using the following definition:
A Counter
a
is contained in a Counterb
if, and only if, for every keyk
ina
, the valuea[k]
is less or equal to the valueb[k]
. TheCounter({'a': 1, 'b': 1})
is contained inCounter({'a': 2, 'b': 2})
but it is not contained inCounter({'a': 2, 'c': 2})
.
I think it is a poor design choice but in python 2.x the comparison operators (<
, <=
, >=
, >
) do not use the previous definition, so the third Counter is considered greater-than the first. In python 3.x, instead, Counter
is an unorderable type.
When you're counting the occurrences of a single object, you can use a single counter. However, when you need to count several different objects, you have to create as many counters as unique objects you have. To count several different objects at once, you can use a Python dictionary.
A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts.
most_common(n)This method returns the most common elements from the counter. If we don't provide value of 'n' then sorted dictionary is returned from most common the least common elements.
While Counter
instances are not comparable with the <
and >
operators, you can find their difference with the -
operator. The difference never returns negative counts, so if A - B
is empty, you know that B
contains all the items in A
.
def contains(larger, smaller):
return not smaller - larger
The best I came up with is to convert the definition i gave in code:
def contains(container, contained):
return all(container[x] >= contained[x] for x in contained)
But if feels strange that python don't have an out-of-the-box solution and I have to write a function for every operator (or make a generic one and pass the comparison function).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With