I have a somewhat complex data structure: a default ordered dictionary of ordered dictionaries, following what's coded here. The class works fine, as I'm able to create ordered dictionaries by default if a key is missing. I would like to further extend the capability of this class, and override the __iter__
method so that I can iterate only over the ordered dictionary of certain key. That is, if I have
import sys
import numpy as np
from collections import OrderedDict
class OrderedDefaultdict(OrderedDict):
def __init__(self, *args, **kwargs):
self.d = None
if not args:
self.default_factory = None
else:
if not (args[0] is None or callable(args[0])):
raise TypeError('first argument must be callable or None')
self.default_factory = args[0]
args = args[1:]
super(OrderedDefaultdict, self).__init__(*args, **kwargs)
def __iter__(self):
for k in self[self.d].values():
yield k
def __call__(self, key):
self.d = key
return self
def __missing__ (self, key):
self.d = max(self.d, key) if self.d else key
if self.default_factory is None:
raise KeyError(key)
self[key] = default = self.default_factory()
return default
def __reduce__(self): # optional, for pickle support
args = (self.default_factory,) if self.default_factory else ()
return self.__class__, args, None, None, self.iteritems()
Tree = lambda: OrderedDefaultdict(Tree)
You see that the code saves the maximum key in a variable self.d
, and I would like to iterate over its corresponding dictionary by default.
def main(argv=()):
tree = Tree()
tree[0]['n1'] = np.array([[3]])
tree[1]['l2'] = np.array([[ 0, 4],
[ 4, 5],
[40, 41],
[41, 42],
[57, 3],
[57, 3]])
tree[2]['t3x'] = np.array([[188, 401, 400],
[188, 187, 401],
[187, 205, 401],
[324, 306, 417],
[306, 305, 417],
[305, 416, 417]])
tree[2]['q3'] = np.array([[188, 401, 400, 0],
[188, 187, 401, 0],
[187, 205, 401, 0],
[323, 324, 417, 0],
[324, 306, 417, 0],
[306, 305, 417, 0],
[305, 416, 417, 0]])
for el in tree:
print(el)
return 0
if __name__ == "__main__":
sys.exit(main())
In the code above, I try to iterate over the dictionary of the highest dimension. But this code doesn't work because I get into an infinite recursion in the __iter__
method and I can't understand why. I've been following advice on how to implement this function here.