collections.Counter 的按位 AND 究竟在做什么?

What exactly is the bitwise AND doing with collections.Counter?

有一个 的正确答案让我非常惊讶,在两个计数器上使用 & 然后“正确”。

来自docs

Counters support rich comparison operators for equality, subset, and superset relationships: ==, !=, <, <=, >, >=. All of those tests treat missing elements as having zero counts so that Counter(a=1) == Counter(a=1, b=0) returns true.

但这并没有涉及 & 的细节。我写了一个小测试脚本:

from collections import Counter
from pprint import pp

cls = Counter  # `dict` fails: TypeError: unsupported operand type

o1 = cls(a=1,b=2,c=3,de=3,f=3,i1=9)
o2 = cls(a=1,b=2,c=3,de=5,f=6,i2=9)
res = o1 & o2

pp(dict(o1=o1,o2=o2,res=res))

输出是:

{'o1': Counter({'i1': 9, 'c': 3, 'de': 3, 'f': 3, 'b': 2, 'a': 1}),
 'o2': Counter({'i2': 9, 'f': 6, 'de': 5, 'c': 3, 'b': 2, 'a': 1}),
 'res': Counter({'c': 3, 'de': 3, 'f': 3, 'b': 2, 'a': 1})}

在我看来counter1 & counter2意味着:

我说的对吗?除了 Counterset 之外,是否还有任何其他标准库数据结构也定义了 __and__(IIRC & 的后盾)?

你的理解很正确。 If you look a couple lines down from where you've quoted,您将看到在 Counter 对象上使用 & 的示例——您无需深入研究源代码即可找到它:

Intersection and union return the minimum and maximum of corresponding counts. ...

>>> c & d                       # intersection:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d                       # union:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})

根据 official docs:

>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d                       # add two counters together:  c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d                       # subtract (keeping only positive counts)
Counter({'a': 2})
>>> c & d                       # intersection:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d                       # union:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})
>>> c == d                      # equality:  c[x] == d[x]
False
>>> c <= d                      # inclusion:  c[x] <= d[x]
False

还定义了一元运算:

>>> c = Counter(a=2, b=-4)
>>> +c
Counter({'a': 2})
>>> -c
Counter({'b': 4})

容器docs状态:

Several mathematical operations are provided for combining Counter objects to produce multisets (counters that have counts greater than zero). Addition and subtraction combine counters by adding or subtracting the counts of corresponding elements. Intersection and union return the minimum and maximum of corresponding counts. Equality and inclusion compare corresponding counts. Each operation can accept inputs with signed counts, but the output will exclude results with counts of zero or less.

要解决您关于其他 dict 衍生物覆盖 & 的问题,我不这么认为。而set(这里是docs)是用&|-^来实现交、并、差、对称差。