Union of many Counters

无人久伴 提交于 2019-12-04 04:28:33

问题


What's the best way (in terms of readability and efficiency) of finding the union of a list of Counters?

For example, my list might look like this:

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

I want to calculate the union, i.e. counters[0] | counters[1] | counters[2] | ....

One way of doing it would be this:

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

Is there a better approach?


回答1:


Goodness, when did Python programmers become afraid of easy loops? LOL.

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

There really aren't prizes in real life for squashing things into as few characters as theoretically possible. Well, ya, there are in Perl, but not in Python ;-)

Later: pursuant to user2357112's comment, starting with Python 3.3 the code above will do "in place" unions into result. That is, result is truly reused, possibly growing larger on each iteration.

In any spelling of

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

instead, the entire partial result so far keeps getting thrown away when the next partial result is computed. That may - or may not - be a lot slower.




回答2:


I think a loop is much more readable:

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



回答3:


user2357112 and Tim's comments made me realize that if you are going to use reduce, you should at least use operator.ior, not operator.or_. In Python 3.3+, this will avoid creating a new counter for every iteration.

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


来源:https://stackoverflow.com/questions/18839875/union-of-many-counters

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!