2016-08-17 1 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'}} 

Так что я должен действительно преобразовать в тип юникода это два целых числа 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 «Юникод», который я использовал в этой строке, - это встроенная функция, конвертирующая 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 
Смежные вопросы