0 写在前面
最近看到一篇CSDN,里面巧妙运用了字典的引用传递和dict.setdefault(key, default=None)方法,有点绕打算细细记录一下。本篇的中心思想在于实现字典嵌套方面。
1 一马当先
首先看如下demo
data = {}
tmp = {'b': 1}
data['a'] = tmp
print(data) # {'a': {'b': 1}}
以上是没有使用引用传递的,我们知道字典每个元素都是一个键-值对(key-value),而巧妙的地方在于值也可以是另外一个字典,这样就能实现嵌套,但是以上的代码比较难以实现嵌套,没有一个可以循环的机制,即应有一个简单的方法使得最里层的值变成可变的字典对象,当然你也可以重新来一个
tmp={}
data['a']['b']=tmp
但是每次带这么多下标不好做循环,也就不能一直嵌套,也不有趣。
2 二话不说
我们可以改变一下,稍稍使用引用传递,,如下
data = {}
tmp = {}
data['a'] = tmp
print(data) # {'a': {}}
tmp['b'] = 1
print(data) # {'a': {'b': 1}}
即每次把tmp赋值给data相应的键值,然后在不断改变tmp就可,
这个在做循环嵌套时还需要引用一个中间量sub_tmp,如下:
data = {}
tmp = data
sub_tmp={}
tmp['a'] = sub_tmp
tmp = sub_tmp # 不可改为{},这不仅是传递值还传递地址,即引用传递
print(sub_tmp) # {}
print(data) # {'a': {}}
tmp['b']={}
print(data)# {'a': {'b': 1}}
第二行data赋给tmp后,tmp的值是{},位置在第一层嵌套中,也可以说是外面的大括号中,第三行开始引入sub_tmp,然后给tmp赋一个键-值对,此时data的值是{'a': {}}
,tmp的值和位置跟data一样,而sub_tmp的值是{}
,位置在{'a': {}}
里面的大括号,到了tmp = sub_tmp,tmp的值和位置变成sub_tmp,通过sub_tmp这个中间量我们的tmp每次位置都会在最里层的字典的值这里,并且值为{}
即空字典,我们可以不断循环中间几行代码来做到无限或者循环嵌套。
3 三羊开泰
上面可以说是无视编程语言的通用方法,但是在python中我们有dict.setdefault(key, default=None)这样的好方法,首先在返回值上跟dict.get()一样,都返回相应key的值,但是dict.setdefault(key, default=None)另外还会给字典dict相应的key赋值,默认是None,如果dict不存在这个key,就会自动生成这个键-值对,具体参考菜鸟教程,这样的好处就是既能消减重复又能重新创建,具体实例参考前面提到的CSDN。
data = {}
tmp = data # 这里不能是tmp={},不然就不能引用传递,并且后面改变tmp时data始终不变
tmp = tmp.setdefault('a',{}) # 这一步既创建了第一层嵌套,而且把最里层的值即这里的{}的值和位置都给了tmp
print(data) # {'a': {}}
tmp = tmp.setdefault('b', {})
print(data) # {'a': {'b': {}}}
tmp['c'] = 1
print(data) # {'a': {'b': {'c': 1}}}
如上,其实思路跟第二节一样,先创建,然后移位,不同的是python中有这样巧妙的dict.setdefault(key, default=None)方法。