Объединение двух словарей по умолчанию

Пытаюсь создать объединение двух словарей по умолчанию. Вот код для метода в моем классе:

def __add__(self,right):
    mergedbag = copy.copy(self.bag_value)
    for item in right:
        if item not in mergedbag:mergedbag[item] = 0
        mergedbag[item] += right[item]
    return mergedbag

Я создаю два словаря по умолчанию:

b = Bag(['d','a','b','d','c','b','d'])
c = Bag(['d','a','b','d','c','b','d'])

результат

print(b+c)

должно быть общее количество элементов после объединения..

Bag(a[a],b[4],c[3],d[6])

Это ошибка, которую я продолжаю получать:

    Traceback (most recent call last):
  File "D:\workspace33\courselib\driver.py", line 229, in driver

Command[print(b+c)]:     exec(old,local,globl)
  File "<string>", line 1, in <module>
  File "D:\workspace33\Project2\src\bag.py", line 58, in __add__
    mergedbag[item] += right[item]
TypeError: 'Bag' object is not subscriptable

Вот новый код:

class Bag:
def __init__(self, items = []):
    self.bag_value = defaultdict(int)
    for item in items:
        self.bag_value[item] += 1


def __repr__(self):
    bag_list = []
    for item, count in self.bag_value.items():
        bag_list.extend(list(item*count))
    return 'Bag(' + str(bag_list) + ')'



def __str__(self):
    return 'Bag(' + ','.join(str(item) + '[' + str(count) + ']' for item, count in self.bag_value.items()) + ')'



def __len__(self):
    bag_len = 0
    for value in self.bag_value:
        bag_len += self.bag_value[value]
    return bag_len



def unique(self):
    return len(self.bag_value)




def __contains__(self, item):
    return item in self.bag_value



def count(self, item):
    return(self.bag_items.count(item))



def add(self, new):
    self.bag_value[new] += 1



def __add__(self,right):
    mergedbag = copy.copy(self.bag_value)
    for item in right:
        if item not in mergedbag:mergedbag[item] = 0
        mergedbag[item] += right[item]
    return mergedbag



def remove(self, item):
    if item in self.bag_items:
        del(item)
    else:
        raise ValueError(type_as_str(item) + ' not in bag.')



def __eq__(self, right):
    if type(right) is not Bag:
        raise TypeError('Cannot compare Bag with' + type_as_str(right) + '. Can only compare Bag with Bag')
    else:
        return (len(self) == len(right)) and  (self.unique() == right.unique())



def __ne__(self, right):
    return not self.__eq__(right)



def _bag_gen(self, bag_value):
    for item in self.bag_value:
        for count in range(self.bag_value[item]):
            yield item



def __iter__(self):
    return self._bag_gen(self.bag_value)



if __name__ == '__main__':
#     bag = Bag(['d','a','b','d','c','b','d'])
#     bag2 = Bag(['d','a','b','d','c','b','d'])
#     bag3 = Bag(['d','a','b','d','c','b'])
#     print(bag == bag2)
#     print(bag == bag3)
#     print(bag != bag2)
#     print(bag != bag3)
    import driver
    driver.driver()

2 ответа

Решение

Прежде всего, важно отметить, что ваш класс Bag в основном совпадает с классом Counter. Если вам нужно какое-то конкретное расширение, просто наследуйте его, и все готово. Я бы сказал, что следующий код просто обращается ко всем функциям, которые вы реализуете сами в своем классе Bag:

from collections import Counter

class Bag(Counter):
    pass

b = Bag(['d','a','b','d','c','b','d'])
c = Bag(['d','a','b','d','c','b','d'])

print (b)
print (c)
print (b+c)

Если вы выполняете упражнение на изучение, проблема в том, что вы не реализуете методы setitem и getitem в своем классе Bag, чтобы разрешить нотацию []. Вы можете реализовать их или просто получить доступ к атрибуту bag_value:

def __add__(self, right):
    mergedbag = Bag()
    mergedbag.bag_value = copy.copy(self.bag_value)
    for item in right.bag_value.keys():
        mergedbag.bag_value[item] += right.bag_value[item]
    return mergedbag

Обязательно создайте и верните объект Bag

Определение

def __add__(self,other):

Таким образом, вы должны объединить содержимое self.items с other.items а затем вернуть результат.

Кроме того, не уверен, если bag1+bag2 будет работать, но мой pyfu слаб, вам придется явно перебирать их и суммировать.

import copy

c = {'a':2,'b':1}
d = {'b':1,'c':1}

#
mergedBag = copy.copy(c) #might wanna use deepcopy?
for k in d:
    if k not in mergedBag: mergedBag[k] = 0
    mergedBag[k] += d[k]

print mergedBag
Другие вопросы по тегам