我需要一个存储字典的字典数据结构,如下所示:

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/

10-12 16:35