Unión de muchos contadores

¿Cuál es la mejor manera (en términos de legibilidad y eficiencia) de encontrar la unión de una lista de contadores ?

Por ejemplo, mi lista podría verse así:

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

Quiero calcular la unión, es decir, counters[0] | counters[1] | counters[2] | ... counters[0] | counters[1] | counters[2] | ... counters[0] | counters[1] | counters[2] | ...

Una forma de hacerlo sería esta:

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

¿Hay un mejor enfoque?

Por Dios, ¿cuándo los progtwigdores de Python se asustaron con los bucles fáciles? Jajaja

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

Realmente no hay premios en la vida real por aplastar cosas en tan pocos personajes como teóricamente sea posible. Bueno, ya están en Perl, pero no en Python 😉

Más tarde: de acuerdo con el comentario de user2357112, comenzando con Python 3.3, el código anterior hará que las “en su lugar” se conviertan en result . Es decir, el result realmente se reutiliza, posiblemente creciendo en cada iteración.

En cualquier ortografía de

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

en cambio, el resultado parcial completo hasta el momento sigue siendo desechado cuando se calcula el siguiente resultado parcial. Eso puede, o no, ser mucho más lento.

Creo que un bucle es mucho más legible:

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

El usuario2357112 y los comentarios de Tim me hicieron darme cuenta de que si va a usar reduce , al menos debe usar operator.ior , no operator.or_ . En Python 3.3+, esto evitará crear un contador nuevo para cada iteración.

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