找到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())
有更好的方法吗?
答案 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())