许多柜台的联盟

时间:2013-09-17 01:25:55

标签: python counter

找到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())

有更好的方法吗?

3 个答案:

答案 0 :(得分:7)

天哪,Python程序员何时害怕轻松循环? LOL。

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

在现实生活中真的没有奖品可以把东西压缩成理论上可能的角色。嗯,你有Perl,但不是Python; - )

后来:根据user2357112的评论,从Python 3.3开始,上面的代码将“就地”联合进入result。也就是说,result是真正重用的,可能在每次迭代时都会变大。

任何

的拼写
counters[0] | counters[1] | counters[2] | ...

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

答案 1 :(得分:2)

我认为循环更具可读性:

def counter_union(iterable):
    union = Counter()
    for counter in counters:
        union |= counter
    return union

答案 2 :(得分:2)

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

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