如何使用以下定义测试另一个python Counter
是否包含 :
计数器
a
包含在计数器b
中,当且仅当k
中的每个键a
的值a[k]
时}小于或等于值b[k]
。Counter({'a': 1, 'b': 1})
中包含Counter({'a': 2, 'b': 2})
,但未包含在Counter({'a': 2, 'c': 2})
中。
我认为这是一个糟糕的设计选择,但在python 2.x 比较运算符(<
,<=
,>=
,{{1} })不要使用先前的定义,因此第三个计数器被认为是大于的第一个。在python 3.x 中,>
是无法解决的类型。
答案 0 :(得分:9)
虽然Counter
个实例与<
和>
运算符不具有可比性,但您可以找到它们与-
运算符的区别。差异永远不会返回负数,因此如果A - B
为空,则表示B
包含A
中的所有项目。
def contains(larger, smaller):
return not smaller - larger
答案 1 :(得分:6)
我想出的最好的方法是转换我在代码中给出的定义:
def contains(container, contained):
return all(container[x] >= contained[x] for x in contained)
但是如果感觉很奇怪,python没有开箱即用的解决方案,我必须为每个运营商编写一个函数(或者创建一个通用函数并传递比较函数) )。
答案 2 :(得分:0)
对于较小Counter
中的所有键,请确保没有值大于Counter
中的对应值:
def containment(big, small):
return not any(v > big[k] for (k, v) in small.iteritems())
>>> containment(Counter({'a': 2, 'b': 2}), Counter({'a': 1, 'b': 1}))
True
>>> containment(Counter({'a': 2, 'c': 2, 'b': 3}), Counter({'a': 2, 'b': 2}))
True
>>> print containment(Counter({'a': 2, 'b': 2}), Counter({'a': 2, 'b': 2, 'c':1}))
False
>>> print containment(Counter({'a': 2, 'c': 2}), Counter({'a': 1, 'b': 1})
False
答案 3 :(得分:0)
另一种相当简洁的表达方式:
“计数器 A 是计数器 B 的子集”等价于 (A & B) == A
。
那是因为两个 Counters 的交集 (&
) 具有两者共有的元素计数。如果 A
的每个元素(计数多重性)也在 A
中,则这将与 B
相同;否则会更小。
性能方面,这似乎与 Blckknght 提出的 not A - B
方法大致相同。按照 enrico.bacis 的答案检查每个键要快得多。
作为一种变体,您还可以检查联合是否等于更大的 Counter(因此没有添加任何内容):(A | B) == B
。对于我测试过的一些较大的多重集(1,000,000 个元素),这明显变慢了。