2017-02-13 36 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 
}] 
} 

助けてください、私が解決しようとしてきましたそれは失敗しました。すでに他の回答を確認していて、全く助けてくれなかったので、重複していないようにしてください。

編集1: 入力は基本的に、そのマッピングタイプ、例えば<String, List> ある辞書dicから取られる:刺激はキーである「刺激」=> [1,3,5,7,8] 、ページ番号のリストにマップされます。 これは基本的にouter forループで読み込まれます。ここで、keyはキーワードであり、valueはそのキーワードの出現ページのリストです。

編集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) 
01 :)

に選択する自由を感じます

これは同じ考えです。まず、jsonで直接保存するために大きなjson_dictを作成します。私はあなたのjson出力で、将来改善する必要がある場合はjson.dumps()のドキュメントに見ている必要があり、また、exception

のキャッチを回避JSONを保存するためにwithステートメントを使用します。

EDIT

そして、ちょうど楽しみのために、あなたはtmp VARが気に入らない場合、あなたはワンライナー内のすべてのデータ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あなたが希望する出力としてあなたjsonを保存したいのですが、にabbleことはありませんように見えます2

にそれを読んで。

実際には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) 

datadf前に来るのでしかし、"filename":がリストの最後に印刷され、ここで一つの問題はまだあります。

注文を強制するには、dictの生成にOrderedDictを使用する必要があります。それは、

{ 
    "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 
       } 
      ] 
     } 
    ] 
} 

しかし、気をつけても、ほとんどの時間:

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) 

ウィル出力);構文は醜い(IMO)ここでpython 2.X

である新しい完全なソリューションであるように注意してください十字言語になるために普通の.jsonファイルを保存する方が良いです。

+1

あなたはそれを上司に釘付けにした。 –

2

あなたの現在のコードは},を追加する前に、最後の項目をループの反復処理しているため機能していないが、それはフラグをfalseに設定しますが、それが最後に実行されたときには,が追加されました。それは別の要素があると思ったからです。

これはあなたの辞書である場合: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は、別の解決策ここでは、私にはよさそうだ何@

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

ご迷惑をおかけして申し訳ございませんが、私はJSONファイルを読んでいません。辞書からJSON出力を作成する必要があります。** 1 **を編集してください。 –

+0

@AsifAli更新された回答を確認できますか? –

+0

**予期した出力**のように再フォーマットしてください。私はそれを試し、様々なエラーを得ることに終わった。それは助けになるだろうし、私も同様に答えを受け入れるよ、努力のおかげで –

関連する問題