4

找到Counters列表并集的最佳方法(就可读性和效率而言)是什么?

例如,我的列表可能如下所示:

counters = [Counter({'a': 6, 'b': 3, 'c': 1}),
            Counter({'a': 2, 'b': 5}),
            Counter({'a': 4, 'b': 4}),
            ...]

我想计算工会,即counters[0] | counters[1] | counters[2] | ...

一种方法是:

def counter_union(iterable):
    return functools.reduce(operator.or_, iterable, Counter())

有更好的方法吗?

4

3 回答 3

7

天哪,Python 程序员什么时候开始害怕简单的循环了?哈哈。

result = Counter()
for c in counters:
    result |= c

在现实生活中,将事物压缩成理论上尽可能少的角色确实没有奖品。好吧,是的,Perl 中有,但 Python 中没有;-)

后来:根据 user2357112 的评论,从 Python 3.3 开始,上面的代码将“就地”联合到result. 也就是说,result真正被重用,可能在每次迭代中变得更大。

在任何拼写

counters[0] | counters[1] | counters[2] | ...

相反,到目前为止,当计算下一个部分结果时,整个部分结果都会被丢弃。这可能——也可能不会——慢得多。

于 2013-09-17T01:32:20.560 回答
3

user2357112 和 Tim 的评论让我意识到,如果你要使用reduce,你至少应该使用operator.ior,而不是operator.or_. 在 Python 3.3+ 中,这将避免为每次迭代创建一个新计数器。

def counter_union(iterable):
    return functools.reduce(operator.ior, iterable, Counter())
于 2013-09-18T03:09:15.650 回答
2

我认为循环更具可读性:

def counter_union(iterable):
    union = Counter()
    for counter in counters:
        union |= counter
    return union
于 2013-09-17T01:33:20.737 回答