Python中的计数器可以这样比较吗?

3 投票
1 回答
5875 浏览
提问于 2025-04-17 15:20

如果你像这样比较两个计数器:

counter_a == counter_b

你会得到一个结果,要么是True(真),要么是False(假)。但是,如果你用 reduceoperator.eq 来比较它们,你会得到False。有人能告诉我这是怎么回事吗?

这里有个例子:

>>> import collections
>>> import operator
>>> a = ['ab', 'ab', 'ab']
>>> b = ['bc', 'ab', 'something']
>>> counters_a = map(collections.Counter, a)
[Counter({'a': 1, 'b': 1}), Counter({'a': 1, 'b': 1}), Counter({'a': 1, 'b': 1})]
>>> counters_b = map(collections.Counter, b)
[Counter({'c': 1, 'b': 1}), Counter({'a': 1, 'b': 1}), Counter({'e': 1, 'g': 1, 'i': 1, 'h': 1, 'm': 1, 'o': 1, 'n': 1, 's': 1, 't': 1})]
>>> counters_a[0] == counters_a[1]
True
>>> counters_b[0] == counters_b[1]
False
>>> reduce(operator.eq, [1, 1, 1])
True
>>> reduce(operator.eq, [1, 1, 2])
False
>>> reduce(operator.eq, counters_b)
**False**
>>> reduce(operator.eq, counters_a)
**False**

1 个回答

12

我觉得你对 reduce 的功能有些误解。根据你的输入,reduce 的工作方式是这样的:

((counters_a[0] == counters_a[1]) == counters_a[2])

它会把一个布尔值 TrueFalse 和另一个计数器进行比较。计数器和布尔值是 永远 不会相等的。reduce 首先对前两个元素进行操作,然后把这个操作的结果作为下一轮循环的输入,再加上列表中的下一个元素。

因为 Python 的 boolean 类型是 int 的一个子类,所以它和 1 是可以比较的(在 Python 中 True == 1True)。如果你对所有的 2 值做同样的操作,它就会失败:

>>> reduce(operator.eq, [2, 2, 2])
False

如果你想检查所有计数器是否相同,可以用 all() 来代替:

>>> all(counters_a[0] == c for c in counters_a[1:])
True
>>> all(counters_b[0] == c for c in counters_b[1:])
False

撰写回答