在python中有序字典的有序字典 [英] ordered dictionary of ordered dictionaries in python
问题描述
我需要一个字典数据结构来存储字典,如下所示:
I need a dictionary data structure that store dictionaries as seen below:
custom = {1: {'a': np.zeros(10), 'b': np.zeros(100)},
2: {'c': np.zeros(20), 'd': np.zeros(200)}}
但问题是我在代码中多次遍历这个数据结构。每次迭代它,我需要遵循迭代的顺序,因为这个复杂数据结构中的所有元素都被映射到一个1D数组(如果你愿意的话),因此这个顺序很重要。我考虑为这个问题写一个订购的 dict
,但我不知道这是正确的解决方案似乎我可能选择错误的数据结构。对于我的案件来说,最合适的解决方案是什么?
But the problem is that I iterate over this data structure many times in my code. Every time I iterate over it, I need the order of iteration to be respected because all the elements in this complex data structure are mapped to a 1D array (serialized if you will), and thus the order is important. I thought about writing a ordered dict
of ordered dict
for that matter, but I'm not sure this is the right solution as it seems I may be choosing the wrong data structure. What would be the most adequate solution for my case?
更新
这是我到目前为止所想到的:
So this is what I came up with so far:
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 __
所以我可以迭代更低的维度。我不喜欢这样的事实,如果列表中没有较低的维度,它不会给我任何错误。我也有一种感觉,每次调用返回自身[self.d] [self.etype] [self.idx-1]
的效率比原来的迭代效率低词典。这是真的?我如何改进这个?
I can iterate as many times as I want in this ordered structure, and I implemented __call__
so I can iterate over the lower dimensions. I don't like the fact that if there isn't a lower dimension present in the list, it doesn't give me any errors. I also have the feeling that every time I call return self[self.d][self.etype][self.idx-1]
is less efficient than the original iteration over the dictionary. Is this true? How can I improve this?
推荐答案
我认为使用 OrderedDict
最好的办法。它们是内置的,比较快:
I think using OrderedDict
s is the best way. They're built-in and relatively fast:
custom = OrderedDict([(1, OrderedDict([('a', np.zeros(10)),
('b', np.zeros(100))])),
(2, OrderedDict([('c', np.zeros(20)),
('d', np.zeros(200))]))])
如果您想要轻松地迭代数据结构的内容,您可以随时提供一个实用功能:
If you want to make it easy to iterate over the contents of the your data structure, you can always provide a utility function to do so:
def iter_over_contents(data_structure):
for delem in data_structure.values():
for v in delem.values():
for row in v:
yield row
请注意,在Python 3.3+中,允许<&cn \\ c $ c>从< expression> ; ,可以消除循环的最后一个:
Note that in Python 3.3+, which allows yield from <expression>
, the last for
loop can be eliminated:
def iter_over_contents(data_structure):
for delem in data_structure.values():
for v in delem.values():
yield from v
其中一个可以写成如下:
With one of those you'll then be able to write something like:
for elem in iter_over_contents(custom):
print(elem)
并隐藏复杂性。
虽然您可以定义自己的类来尝试封装此数据结构,并使用类似 iter_over_contents()
生成器函数作为其 __ iter __()
方法,该方法可能会更慢,不会允许表达式使用两个级别的索引,如以下:
While you could define your own class in an attempt to encapsulate this data structure and use something like the iter_over_contents()
generator function as its __iter__()
method, that approach would likely be slower and wouldn't allow expressions using two levels of indexing such this following:
custom[1]['b']
使用嵌套字典(或 OrderedDefaultdict
s,如我的其他答案所示)将
which using nested dictionaries (or OrderedDefaultdict
s as shown in my other answer) would.
这篇关于在python中有序字典的有序字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!