这是前段时间群里一帮小伙伴发的一道面试题。利用Python字典的特性,可以巧妙地使用简化的代码,达到完美的解决方案。题目将data转换成new_data,并写出转换过程。data={'a_b_h':1,'a_b_i':2,'a_c_j':3,'a_d':4,'a_c_k':5,'a_e':6}new_data={'a':{'b':{'h':1,'i':2},'c':{'j':3,'k':5},'d':4,'e':6}}可以看出也就是说,转换过程是将key的下划线拆分,然后将下划线后面的字符嵌套在前一个字符的值中。有兴趣的可以打开IDE自己尝试解决。你应该很快想到解决问题的思路。主要思路是拆分下划线,然后依次使用字符生成内层字典,到达最后一个字符时使用数字作为值。那么重点来了,如何不断获取内部字典进行修改呢?其实这道题就是考查你是否理解Python字典引用传递的特性。什么是引用传递?我们知道Python中的字典和列表对象是可变对象。它们的变量传递给另一个变量后,改变对象元素会导致两个变量同时改变,例如:new_data={}tmp={}new_data['a']=tmpprint(new_data)#{'a':{}}tmp['b']=1print(new_data)#{'a':{'b':1}}同上,利用这个特性,内层将字典赋给一个中间变量,然后更改中间变量以同步修改最终的new_data变量。按照这个思路,初步代码如下:data={'a_b_h':1,'a_b_i':2,'a_c_j':3,'a_d':4,'a_c_k':5,'a_e':6}new_data={}forkey,valueindata.items():keys=key.split('_')tmp=new_datalast=len(keys)-1#最后一个键的索引值fori,kinenumerate(keys):ifi==last:tmp[k]=valuecontinueifknotintmp:sub_tmp={}tmp[k]=sub_tmptmp=sub_tmpelse:tmp=tmp[k]这也是第一个版本群友给出的答案是,这样写问题不大,只是代码比较繁琐,肯定有优化的空间。我们可以只使用一个中间变量来进一步优化:forfield,valueindata.items():keys=field.split('_')tmp=new_datalast=len(keys)-1fori,kinenumerate(keys):ifknotintmp:tmp[k]={}ifi
