Python字典嵌套字典 – blueattack – 博客园
Python字典嵌套字典 – blueattack – 博客园
from collections import defaultdict
mm = defaultdict(lambda :defaultdict(defaultdict))
mm[1][2][3] = 4
其实像上面那样做仍然不完美,比如上面的代码,如果写:
- nn = defaultdict(lambda :defaultdict(defaultdict))
- nn[1][2][3][4] = 5
- Traceback (most recent call last):
- File "C:\Users\Administrator\anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3343, in run_code
- exec(code_obj, self.user_global_ns, self.user_ns)
- File "<ipython-input-84-e89eb103c97b>", line 1, in <module>
- nn[1][2][3][4] = 5
- KeyError: 3
马上就会报错。
当然,为了使字典多一层key,可以这样:
mm =defaultdict(lambda: defaultdict(lambda :defaultdict(defaultdict)))
这样就可以这样写了:
mm[1][2][3][4] = 5
但是如果实际编程的时候,需要更多一层key,又会报错。
而且可以看出,在定义mm的时候,有多少个defaultdict,就最多可以有多少层key。
那么有没有办法让mm的key的层数尽可能多一些,满足工作需求呢? 可以用以下办法实现:
- mm = defaultdict(defaultdict)
- for i in range(100):
- ...: mm = defaultdict(lambda:mm)
- ...: pass
- ...:
- mm[1][2][3][4][5][6][7] = 8
这个例子中,循环了100次,一共有102个defaultdict,也就是说mm可以有102层key。
肯定满足需要了。
如果有需要,还可以封装成一个函数
不过,还是感觉没有perl的哈希简单,可以无限嵌套。
- def nest(number):
- mm = defaultdict(defaultdict)
- for i in range(number):
- mm = defaultdict(lambda:mm)
- return(mm)
-
但是看看这个,会让人有些崩溃:
- aa = nest(100)
- aa[1][2] = 'A'
- aa[3][4] = 'B'
- aa.keys()
- Out[192]: dict_keys([1, 2, 3, 4])
- for i in aa.keys():
- ...: print(i)
- ...:
- 1
- 2
- 3
- 4
我的意思,本来是想用第一层的keys,也就是1,3,没想到1,2,3,4都是keys
还可以试试:
- mm = nest(100)
- ...:mm[1][2][3] = 'A'
- ...:mm[4][5][6] = 'B'
- ...:for i in mm:
- ...: for j in mm[i]:
- ...: for k in mm[i][j]:
- ...: print('{}=={}=={}'.format(i,j,k))
输出的结果简直是disaster
以下这个办法似乎管用
- class Vividict(dict):
- def __missing__(self, key):
- value = self[key] = type(self)() # retain local pointer to value
- return value # faster to return than
- # ...'dict lookup'
-
- ydata = Vividict()
- aa = Vividict()
- aa[1][2][3][4] = 5
- aa[5][6][7][8] = 'B'
-
-
- for i in aa:
- ...: for j in aa[i]:
- ...: for k in aa[i][j]:
- ...: for l in aa[i][j][k]:
- ...: print('={}==={}====={}====={}='.format(i,j,k,l))
- ...:
- =1===2=====3=====4=
- =5===6=====7=====8=