2016-01-01 1 views
1

Учитывая, что я знаю, сколько счетчики есть, можно было бы легко твердое ядро ​​с | операторов, чтобы получить объединение счетчиков, например:Как использовать объединение и пересечение в списке счетчиков неизвестной длины?

>>> from collections import Counter 
>>> x = Counter([('a'), ('a', 'bc'), ('a', 'bc'), ('xyz', 'hooli')]) 
>>> y = Counter([('a'), ('a'), ('a'), ('asd', 'asd')]) 
>>> z = Counter([('a'), ('a'), ('a'), ('a'), ('a', 'bc')]) 
>>> x | y | z 
Counter({'a': 4, ('a', 'bc'): 2, ('asd', 'asd'): 1, ('xyz', 'hooli'): 1}) 

Но если у меня есть список счетчиков в качестве вклада как я могу получить союз?

Должен ли я проходить через каждый счетчик, а затем выполнять объединение? Например.

>>> xyz = [x,y,z] 
>>> def counter_union(counters): 
...  union = Counter() 
...  for c in counters: 
...    union = union | c 
...  return union 
... 
>>> counter_union(xyz) 
Counter({'a': 4, ('a', 'bc'): 2, ('asd', 'asd'): 1, ('xyz', 'hooli'): 1}) 

Есть еще один способ сделать это?

ответ

4

Вы можете использовать reduce:

>>> from functools import reduce 
>>> from operator import or_ 
>>> reduce(or_, [x, y, z]) 
Counter({'a': 4, ('a', 'bc'): 2, ('xyz', 'hooli'): 1, ('asd', 'asd'): 1}) 

Или, если вы не хотите импортировать or_: (. Аналогично для and_/&)

>>> reduce(lambda a,b: a|b, [x, y, z]) 
Counter({'a': 4, ('a', 'bc'): 2, ('xyz', 'hooli'): 1, ('asd', 'asd'): 1}) 

+0

Благодаря @DSM, что упрощает код довольно много! – alvas

+0

В соответствии с ошибкой 'operator.ior' будет избегать создания нового счетчика каждый раз, когда' reduce (ior, [x, y, z], Counter()) ' –