2016-08-17 105 views
0

想象一下,我有一个名为包含以下字典的文本“test_dict.txt”文件:的Python:如何修改值嵌套字典和拥有整个字典返回

{ 
    "subdic1" : { 
     "a_string" : "something1", 
     "a_integer" : 16, 
     "a_list" : [ 
      "str_1", 
      "str_2" 
     ] 
    }, 
    "subdic2" : { 
     "a_string" : "something2", 
     "a_integer" : 32, 
     "a_list" : [ 
      "str_3", 
      "str_4" 
     ] 
    } 
} 

正如你所看到的有嵌套字典。我想要做的是将所有最深的值(“something1”,16,[“str_1”,“str_2”]等)转换为unicode类型的对象,以进行一些比较。这是我的尝试:

import json 
from copy import deepcopy 

def to_unicode(d): 
    dc = deepcopy(d) 
    for k,v in dc.iteritems(): 
     if isinstance(v, dict): 
      to_unicode(v) 
     else: 
      dc[k] = unicode(v) 
    return dc 

dict_fname = 'test_dict.txt' 
with open(dict_fname) as dict_fd: 
    dic = json.load(dict_fd) 
print dic 
print to_unicode(dic) 

我在我的函数'to_unicode'中使用递归来遍历最深的值。第一个“打印”给出的“json.load”的结果类似下面的操作:

{u'subdic1': {u'a_list': [u'str_1', u'str_2'], u'a_integer': 16, u'a_string': u'something1'}, u'subdic2': {u'a_list': [u'str_3', u'str_4'], u'a_integer': 32, u'a_string': u'something2'}} 

所以,我真的应该转换为Unicode类型是两个整数16和32,但我还是希望函数为了简单起见,转换每个字典级别中的每个值。这两个数字都应该被转换成u'16' 和u'32' ,所以由该函数返回的字典对象应印像这样:

{u'subdic1': {u'a_list': [u'str_1', u'str_2'], u'a_integer': u'16', u'a_string': u'something1'}, u'subdic2': {u'a_list': [u'str_3', u'str_4'], u'a_integer': u'32', u'a_string': u'something2'}} 

但实际上我的第二个‘打印’给出了与第一个结果完全相同的结果。我猜这个问题要么发生在深层拷贝中,要么发生在函数返回的方式中,或者两者兼而有之。我真的希望整个字典在转换后返回,而不是一次产生一个项目。请有人帮忙纠正我的代码吗?

+0

'dc [k] = to_unicode(v)'? – jonrsharpe

+0

@jonrsharpe我在这行中使用的'unicode'是内置函数,将v转换为unicode类型,然后将其分配回相应的键。 –

+1

是的,但你不会在每次递归调用时分配回“主副本”,而是创建子树的新副本并更新其中的一部分。因此我的建议如上。投入一些“印刷品”,看看发生了什么。 – jonrsharpe

回答

0

正如@jonrsharpe所提到的,您只需将事物分配回主或原始副本即可。这里有一些意见反复提供了您提供的代码:

def to_unicode(d, target_dict={}): 
    for k,v in d.iteritems(): 
     if isinstance(v, dict): 
      target_dict = to_unicode(v, target_dict) 
     else: 
      target_dict[k] = unicode(v) 
    return target_dict