Объединение двух словарей по умолчанию
Пытаюсь создать объединение двух словарей по умолчанию. Вот код для метода в моем классе:
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