Вложенный, бесконечный словарь в python - PullRequest
2 голосов
/ 20 марта 2012

Я хочу установить ключи и значения в словаре.Вот пример того, что я делаю.

class NestedDict(dict):
    def __getitem__(self, key):
        if key in self: return self.get(key)
        return self.setdefault(key, NestedDict())

>>> c = NestedDict()
>>> c
{}
>>> c['a']['b'] = 'test'
>>> c['a']['c'] = 2
>>> c
{'a': {'c': 2, 'b': 'test'}}
>>> c['a']['c'] += 1
>>> c
{'a': {'c': 3, 'b': 'test'}}
>>> c['a']['d'] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +=: 'NestedDict' and 'int'

Есть идеи, как решить эту проблему?Я хочу быть в состоянии использовать + = и - =.Конечно, если значение не существует, то + = 1 это то же самое, что и = 1. Может быть, есть лучшее решение?

Спасибо.

Ответы [ 3 ]

11 голосов
/ 20 марта 2012

Поскольку d не существует в c['a'], какое поведение вы ожидаете, когда пытаетесь добавить 1 к нему?Сначала он вызовет __getitem__, не найдет ключ, а затем вернет NestedDict, который не поддерживает добавление на месте с int.

Кстати, мне кажется, что вы пытаетесь реализовать словарь со значением "по умолчанию".Я бы использовал класс defaultdict, доступный в модуле коллекций, вот так:

from collections import defaultdict

def create_nested_dict():
   return defaultdict(create_nested_dict)

c = create_nested_dict()
1 голос
/ 20 марта 2012

Поскольку у вас есть контроль над вашими объектами, помещенными во вложенный dict, просто определите сложение и вычитание для них таким образом, что при добавлении к объекту он просто возвращает другой объект (фактически ведет себя как числовой 0 при добавлении к числам). ):

class NestedDict(dict):
    def __getitem__(self, key):
        if key in self: return self.get(key)
        return self.setdefault(key, NestedDict())
    def __add__(self, other):
        return other
    def __sub__(self, other):
        return other

И вуаля:

>>> n = NestedDict()
>>> n["a"]["b"] += 1
>>> n["a"]["b"]
1
1 голос
/ 20 марта 2012

Прежде всего, setdefault() уже возвращает self[key], если он существует, вам не нужна первая строка вашего __getitem__().

Что касается вашей проблемы, вы не можете это сделать. По крайней мере, не с вашим существующим кодом. Вы уже создаете NestedDict для каждого несуществующего узла. Теперь вы хотите, чтобы некоторые из них были числами?

Возможно, вам следует создать динамический класс узлов, который мог бы функционировать как dict или как число, в зависимости от необходимости?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...