Проблема с методом Python dict __new__ - PullRequest
1 голос
/ 12 февраля 2020

Привет, я делаю этот класс

class multiset(dict):

  def __new__(cls,iterabile):
      d = dict()
      for i in iterabile:
          if i not in d.keys():
              d[i] = iterabile.count(i)
      return super().__new__(cls,d)

Этот класс является пользовательским диктом, который из списка ввода создает диктовку, в которой ключи являются элементом, а значения - числом вхождений элемент keys в списке. Проблема в том, что super () .__ new __ (cls, d) возвращает эту ошибку:

Traceback (последний вызов был последним):

File "", строка 1, в m = multiset ([1,1,1,2,1,3,2,3])

TypeError: невозможно преобразовать элемент последовательности обновления словаря # 0 в последовательность

Ответы [ 2 ]

3 голосов
/ 12 февраля 2020

Перейдите на использование __init__() и не создавайте явный новый dict, потому что self уже является диктом, потому что мультимножество наследует от dict:

class multiset(dict):

  def __init__(self,iterable):
      for i in iterable:
          if i not in self.keys():
              self[i] = iterable.count(i)

m = multiset([1,1,1,2,1,3,2,3])
print( m )
# prints: {1: 4, 2: 2, 3: 2}

Но, как указывает ndclt, collections.Counter уже делает это.

2 голосов
/ 12 февраля 2020

Исходя из документации Python :

Конструктор dict () создает словари непосредственно из последовательностей пар ключ-значение:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}

И вы даете конструктор dict super().__new__(cls,d), который вместо пары ключ-значение вызывает dict.__init__ dict.

Почему бы не использовать Counter который выглядит так, как будто вы делаете то, что вы хотите, и ведете себя как словарь:

>>> from collections import Counter
>>> Counter([1,1,1,2,1,3,2,3])                                                                                                                         
Counter({1: 4, 2: 2, 3: 2})
>>> Counter([1,1,1,2,1,3,2,3])[1]
4
...