我需要一个存储字典的字典数据结构,如下所示:
custom = {1: {'a': np.zeros(10), 'b': np.zeros(100)},
2: {'c': np.zeros(20), 'd': np.zeros(200)}}
但是问题是我在代码中多次遍历此数据结构。每次迭代时,都需要遵循迭代顺序,因为此复杂数据结构中的所有元素都映射到一维数组(如果需要,可以序列化),因此顺序很重要。我考虑过要为此写一个有序
dict
的有序dict
,但是我不确定这是正确的解决方案,因为看来我可能选择了错误的数据结构。什么是最适合我的情况的解决方案?更新
因此,这是我到目前为止提出的:
class Test(list):
def __init__(self, *args, **kwargs):
super(Test, self).__init__(*args, **kwargs)
for k,v in args[0].items():
self[k] = OrderedDict(v)
self.d = -1
self.iterator = iter(self[-1].keys())
self.etype = next(self.iterator)
self.idx = 0
def __iter__(self):
return self
def __next__(self):
try:
self.idx += 1
return self[self.d][self.etype][self.idx-1]
except IndexError:
self.etype = next(self.iterator)
self.idx = 0
return self[self.d][self.etype][self.idx-1]
def __call__(self, d):
self.d = -1 - d
self.iterator = iter(self[self.d].keys())
self.etype = next(self.iterator)
self.idx = 0
return self
def main(argv=()):
tst = Test(elements)
for el in tst:
print(el)
# loop over a lower dimension
for el in tst(-2):
print(el)
print(tst)
return 0
if __name__ == "__main__":
sys.exit(main())
我可以在此有序结构中进行任意多次迭代,并且实现了
__call__
,因此可以在较低维度上进行迭代。我不喜欢这样的事实,即如果列表中没有较小的尺寸,它不会给我任何错误。我还感觉到,每次我调用return self[self.d][self.etype][self.idx-1]
时,效率都比字典上的原始迭代低。这是真的?我该如何改善呢? 最佳答案
这是另一个使用OrderedDefaultdict
定义所需树状数据结构的方法。我正在从我的另一个answer中重用它的定义。
要使用它,您必须确保按照以后要访问它们的顺序定义条目。
class OrderedDefaultdict(OrderedDict):
def __init__(self, *args, **kwargs):
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 __missing__ (self, 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)
custom = Tree()
custom[1]['a'] = np.zeros(10)
custom[1]['b'] = np.zeros(100)
custom[2]['c'] = np.zeros(20)
custom[2]['d'] = np.zeros(200)
我不确定我是否理解您的后续问题。如果数据结构限于两个级别,则可以使用嵌套的
for
循环按其定义的顺序对其元素进行迭代。例如:for key1, subtree in custom.items():
for key2, elem in subtree.items():
print('custom[{!r}][{!r}]: {}'.format(key1, key2, elem))
(在Python 2中,您想使用
iteritems()
而不是items()
。)关于python - python中有序字典的有序字典,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34294481/