python - collections.Counter addition error with counter of counters summation -
suppose have code snippet follows:
from collections import namedtuple, counter experiment = namedtuple('experiment', ['day', 'distribution']) labresults = namedtuple('labresults', ['lab_name', 'experiments_data']) lab_results_list_good = [ labresults( 'lab a', [ experiment('first_day', counter('abc')), experiment('second_day', counter('')) ], ), labresults( 'lab b', [ experiment('first_day', counter('')), experiment('second_day', counter('a')), ] ) ] lab_results_list_bad = [ labresults( 'lab a', [ experiment('first_day', counter('abc')), experiment('second_day', counter('def')) ], ), labresults( 'lab b', [ experiment('first_day', counter('ghi')), ] ) ] def merge_distributions(lab_results_list): day_to_distribution_report = counter() lab_result in lab_results_list: curr_day_to_dist = counter({exp.day: exp.distribution exp in lab_result.experiments_data}) day_to_distribution_report += curr_day_to_dist return day_to_distribution_report first case works fine , second case doesn't work:
in [2]: print merge_distributions(lab_results_list_good) counter({'first_day': counter({'a': 1, 'c': 1, 'b': 1}), 'second_day': counter({'a': 1})}) in [3]: print merge_distributions(lab_results_list_bad) --------------------------------------------------------------------------- typeerror traceback (most recent call last) <ipython-input-3-969bd085f2e5> in <module>() ----> 1 print merge_distributions(lab_results_list_bad) <ipython-input-1-0bdc39e8c846> in merge_distributions(lab_results_list) 42 43 curr_day_to_dist = counter({exp.day: exp.distribution exp in lab_result.experiments_data}) ---> 44 day_to_distribution_report += curr_day_to_dist 45 return day_to_distribution_report /usr/local/cellar/python/2.7.13/frameworks/python.framework/versions/2.7/lib/python2.7/collections.pyc in __add__(self, other) 642 result = counter() 643 elem, count in self.items(): --> 644 newcount = count + other[elem] 645 if newcount > 0: 646 result[elem] = newcount typeerror: unsupported operand type(s) +: 'counter' , 'int' in python 2 doesn't works second case, in python 3 doesn't works both.
so question bad idea merge counter of counters python 3 fails both cases run? seems bug counter object support additions.
edit find out fast fix merge_distribution function:
def merge_distributions(lab_results_list): day_range = {exp.day lab_result in lab_results_list exp in lab_result.experiments_data} day_to_distribution_report = counter() lab_result in lab_results_list: curr_day_to_dist = counter({exp.day: exp.distribution exp in lab_result.experiments_data}) map(lambda day: curr_day_to_dist.setdefault(day, counter()), day_range) day_to_distribution_report += curr_day_to_dist return day_to_distribution_report why python sources not default?
if counter doesn't have property, default 0, not counter()
>>> collections import counter >>> c = counter({ ... 'a': counter(), 'b': counter(), ... }) >>> d = counter({ ... 'a': counter() ... }) >>> c['b'] counter() >>> d['b'] 0 >>> c['b'] + d['b'] traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: unsupported operand type(s) +: 'counter' , 'int' >>> here defaultcounter implements:
from collections import counter class defaultcounter(counter): def __add__(self, other): if not isinstance(other, counter): if other == 0: other = counter() else: return notimplemented result = counter() elem, count in self.items(): newcount = count + other[elem] if newcount > 0: result[elem] = newcount elem, count in other.items(): if elem not in self , count > 0: result[elem] = count return result >>> m import defaultcounter >>> = defaultcounter({'a': defaultcounter(), 'b': defaultcounter()}) >>> b = defaultcounter({'a': defaultcounter()}) >>> >>> + b counter({'a': counter(), 'b': counter()}) # not raise anymore. ^_^
Comments
Post a Comment