2017-02-13 15 views
3

Как проблема объясняет проблему, я пытаюсь создать вложенный объект JSON. В этом случае у меня есть for петли, получающие данные из словаря dic. Ниже приведен код:Создание динамического вложенного объекта JSON и массива - python

f = open("test_json.txt", 'w') 
flag = False 
temp = "" 
start = "{\n\t\"filename\"" + " : \"" +initial_filename+"\",\n\t\"data\"" +" : " +" [\n" 
end = "\n\t]" +"\n}" 
f.write(start) 
for i, (key,value) in enumerate(dic.iteritems()): 
    f.write("{\n\t\"keyword\":"+"\""+str(key)+"\""+",\n") 
    f.write("\"term_freq\":"+str(len(value))+",\n") 
    f.write("\"lists\":[\n\t") 
    for item in value: 
     f.write("{\n") 
     f.write("\t\t\"occurance\" :"+str(item)+"\n") 
     #Check last object 
     if value.index(item)+1 == len(value): 
      f.write("}\n" 
      f.write("]\n") 
     else: 
      f.write("},") # close occurrence object 
    # Check last item in dic 
    if i == len(dic)-1: 
     flag = True 
    if(flag): 
     f.write("}") 
    else: 
     f.write("},") #close lists object 
     flag = False 

#check for flag 
f.write("]") #close lists array 
f.write("}") 

Ожидаемый результат:

{ 
"filename": "abc.pdf", 
"data": [{ 
    "keyword": "irritation", 
    "term_freq": 5, 
    "lists": [{ 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 2 
    }] 
}, { 
    "keyword": "bomber", 
    "lists": [{ 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 2 
    }], 
    "term_freq": 5 
}] 
} 

Но в настоящее время я получаю выход, как показано ниже:

{ 
"filename": "abc.pdf", 
"data": [{ 
    "keyword": "irritation", 
    "term_freq": 5, 
    "lists": [{ 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 2 
    },]    // Here lies the problem "," before array(last element) 
}, { 
    "keyword": "bomber", 
    "lists": [{ 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 1 
    }, { 
     "occurance": 2 
    },],     // Here lies the problem "," before array(last element) 
    "term_freq": 5 
}] 
} 

Пожалуйста, помогите, я пытаюсь решить это, но не удалось. Пожалуйста, не отмечайте его дубликат, так как я уже проверил другие ответы и не помог вообще.

Edit 1: Ввод в основном взяты из словаря dic, тип которого отображение <String, List> , например: «раздражение» => [1,3,5,7,8] где раздражение является ключевым, и отображается на список номеров страниц. Это в основном прочитано во внешнем цикле, где ключ - это ключевое слово и значение - список страниц появления этого ключевого слова.

Edit 2:

dic = collections.defaultdict(list) # declaring the variable dictionary 
dic[key].append(value) # inserting the values - useless to tell here 
for key in dic: 
    # Here dic[x] represents list - each value of x 
    print key,":",dic[x],"\n" #prints the data in dictionary 
+0

Если это правильно сформированный файл 'json', вы можете использовать модуль' json' вместо импорта в качестве текста. Можете ли вы предоставить какие-либо детали вашего входного файла? – asongtoruin

+0

вход длинный процесс, я отредактирую ответ с абстракцией ввода –

+1

Почему вы не используете json.dump, а затем обновляете объект JSON по мере поступления большего количества данных? –

ответ

6

Что @ Андреа-е выглядит хорошо для меня, вот еще одно решение:

Вы можете выбрать в обоих :)

import json 

dic = { 
     "bomber": [1, 2, 3, 4, 5], 
     "irritation": [1, 3, 5, 7, 8] 
     } 

filename = "abc.pdf" 

json_dict = {} 
data = [] 

for k, v in dic.iteritems(): 
    tmp_dict = {} 
    tmp_dict["keyword"] = k 
    tmp_dict["term_freq"] = len(v) 
    tmp_dict["lists"] = [{"occurrance": i} for i in v] 
    data.append(tmp_dict) 

json_dict["filename"] = filename 
json_dict["data"] = data 

with open("abc.json", "w") as outfile: 
    json.dump(json_dict, outfile, indent=4, sort_keys=True) 

Это та же идея, я сначала создаю большой json_dict, который будет сохранен непосредственно в json. Я использую with заявление, чтобы сохранить JSON, избегая улов exception

Кроме того, вы должны взглянуть на документ о json.dumps(), если вам нужно в будущем улучшить в своей json продукции.

EDIT

И просто для удовольствия, если вам не нравится tmp вара, вы можете сделать все данные, for петли в однострочнике :)

json_dict["data"] = [{"keyword": k, "term_freq": len(v), "lists": [{"occurrance": i} for i in v]} for k, v in dic.iteritems()] 

Он мог дал для окончательного решения что-то не полностью читаемым, как это:

import json 

json_dict = { 
       "filename": "abc.pdf", 
       "data": [{ 
         "keyword": k, 
         "term_freq": len(v), 
         "lists": [{"occurrance": i} for i in v] 
         } for k, v in dic.iteritems()] 
      } 

with open("abc.json", "w") as outfile: 
    json.dump(json_dict, outfile, indent=4, sort_keys=True) 

EDIT 2

Похоже, что вы не хотите, чтобы сохранить json как желаемый результат, но быть abble для чтения его.

Фактически вы также можете использовать json.dumps() для того, чтобы распечатать ваш json.

with open('abc.json', 'r') as handle: 
    new_json_dict = json.load(handle) 
    print json.dumps(json_dict, indent=4, sort_keys=True) 

Существует еще одна проблема, хотя здесь, "filename": печатается в конце списка, так как d из data приходит до f.

Чтобы заставить заказ, вы должны использовать OrderedDict в генерации dict. Будьте осторожны, синтаксис уродлив (IMO) с python 2.X

Вот новое комплексное решение;)

import json 
from collections import OrderedDict 

dic = { 
     'bomber': [1, 2, 3, 4, 5], 
     'irritation': [1, 3, 5, 7, 8] 
     } 

json_dict = OrderedDict([ 
       ('filename', 'abc.pdf'), 
       ('data', [ OrderedDict([ 
             ('keyword', k), 
             ('term_freq', len(v)), 
             ('lists', [{'occurrance': i} for i in v]) 
            ]) for k, v in dic.iteritems()]) 
      ]) 

with open('abc.json', 'w') as outfile: 
    json.dump(json_dict, outfile) 


# Now to read the orderer json file 

with open('abc.json', 'r') as handle: 
    new_json_dict = json.load(handle, object_pairs_hook=OrderedDict) 
    print json.dumps(json_dict, indent=4) 

Выведет:

{ 
    "filename": "abc.pdf", 
    "data": [ 
     { 
      "keyword": "bomber", 
      "term_freq": 5, 
      "lists": [ 
       { 
        "occurrance": 1 
       }, 
       { 
        "occurrance": 2 
       }, 
       { 
        "occurrance": 3 
       }, 
       { 
        "occurrance": 4 
       }, 
       { 
        "occurrance": 5 
       } 
      ] 
     }, 
     { 
      "keyword": "irritation", 
      "term_freq": 5, 
      "lists": [ 
       { 
        "occurrance": 1 
       }, 
       { 
        "occurrance": 3 
       }, 
       { 
        "occurrance": 5 
       }, 
       { 
        "occurrance": 7 
       }, 
       { 
        "occurrance": 8 
       } 
      ] 
     } 
    ] 
} 

Но будьте осторожны, большую часть времени, это чтобы сохранить файлы размером .json файл для того, чтобы быть кросс.

+1

Ты прибил его боссом. –

2

Ваш текущий код не работает, потому что цикл повторяется через до-последний пункт добавления }, тогда, когда цикл запускается снова устанавливает флаг ложные, но в прошлый раз он запустил его, добавив ,, поскольку он думал, что будет другой элемент.

Если это ваш ДИКТ: a = {"bomber":[1,2,3,4,5]} то вы можете сделать:

import json 
file_name = "a_file.json" 
file_name_input = "abc.pdf" 
new_output = {} 
new_output["filename"] = file_name_input 

new_data = [] 
i = 0 
for key, val in a.iteritems(): 
    new_data.append({"keyword":key, "lists":[], "term_freq":len(val)}) 
    for p in val: 
     new_data[i]["lists"].append({"occurrance":p}) 
    i += 1 

new_output['data'] = new_data 

Затем сохранить данные:

f = open(file_name, 'w+') 
f.write(json.dumps(new_output, indent=4, sort_keys=True, default=unicode)) 
f.close() 
+0

Прошу прощения, но, пожалуйста, поймите, проблема не в том, что я не читаю JSON-файл любого типа, мне нужно создать JSON-выход из словаря ** Edit 1 **, а не просто прямой вывод, скорее форматированный, как только ожидается output –

+0

@AsifAli вы можете проверить обновленный ответ? –

+0

Не могли бы вы переформатировать его так, как показано в ** ожидаемом выходе **. Я попробовал, в итоге получаю различные ошибки. Это будет полезно, и я также приму ответ, спасибо за усилия –