2012-03-20 5 views
2

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

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. Может быть, есть лучшее решение?

Спасибо.

+0

это потому, что ваш с [ «а»] [ «d»] не имеет значения, так что ваши инициировать его и хотите увеличить что-то. juste do c ['a'] ['d'] = 0, тогда вы можете сделать то, что хотите – lpostula

+2

, когда вы пишете 'c [someNonExistingKey] + = 1', какой результат вы хотите? – georg

+0

Я знаю, но я хочу написать что-то, что автоматически установило бы 0 сначала, если не будет использовано значение = + – eshlox

ответ

1

Поскольку у вас есть контроль над вашими объектами, расположенными внутри вложенного 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 
+0

Отлично. Именно то, что я хотел. Спасибо. – eshlox

10

С 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

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

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

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

Смежные вопросы