10

次の定義を使用して、Python が別の PythonCounter含まれているかどうかをテストする方法:

Counterは、 内のすべてのキーについて、 valueが value 以下である場合にのみa、 Counter に含まれます。は に含まれていますが、には含まれていません。bkaa[k]b[k]Counter({'a': 1, 'b': 1})Counter({'a': 2, 'b': 2})Counter({'a': 2, 'c': 2})

設計上の選択としては不適切だと思いますが、python 2.x では比較演算子 ( <<=>=>) は以前の定義を使用しないため、3 番目の Counter は1 番目よりも大きいと見なされます。Python 3.x では、代わりにCounter順序付けできない型です。

4

4 に答える 4

14

Counterインスタンスは<and演算子と比較できませんが、演算子を>使用すると違いがわかります-。差が負の数を返すことはないため、が空の場合、に のすべての項目が含まれてA - Bいることがわかります。BA

def contains(larger, smaller):
    return not smaller - larger
于 2015-04-11T09:07:48.203 に答える
13

私が思いついた最善の方法は、コードで指定した定義を変換することです。

def contains(container, contained):
    return all(container[x] >= contained[x] for x in contained)

しかし、Python にはすぐに使えるソリューションがなく、すべての演算子に対して関数を作成する (または一般的な関数を作成して比較関数を渡す) 必要があることに奇妙に感じる場合。

于 2015-04-11T08:12:23.803 に答える
1

small のすべてのキーについて、bigerCounterの対応する値よりも大きな値がないことを確認して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
于 2015-04-12T07:46:17.053 に答える
0

これをかなり簡潔に表現するもう 1 つの方法は次のとおりです。

「カウンター A はカウンター B のサブセットです」は と同等(A & B) == Aです。

これ&は、2 つの Counter の交差 ( ) に、両方に共通する要素のカウントがあるためです。これは、 (多重度を数える)Aのすべての要素が;にもある場合と同じです。それ以外の場合は小さくなります。AB

not A - B性能的には、これはBlckknghtが提案した方法とほぼ同じようです。enrico.bacis の回答のように各キーをチェックすると、かなり高速になります。

バリエーションとして、union がより大きな Counter と等しいことを確認することもできます (つまり、何も追加されていません) (A | B) == B。これは、私がテストしたいくつかの大規模なマルチセット (1,000,000 要素) では著しく遅くなります。

于 2021-05-14T03:04:57.020 に答える