python3字典 是有序的,在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)}}

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?

UPDATE

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())

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?

解决方案

I think using OrderedDicts 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

Note that in Python 3.3+, which allows yield from , 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)

and hide the complexity.

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']

which using nested dictionaries (or OrderedDefaultdicts as shown in my other answer) would.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值