2017-02-13 4 views
3

Da die Frage das Problem erklärt, habe ich versucht, geschachtelte JSON-Objekt zu generieren. In diesem Fall habe ich for Schleifen bekommen die Daten aus dem Wörterbuch dic. Unten ist der Code:Erstellen eines dynamischen verschachtelten JSON-Objekts und -Arrays - 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("}") 

Erwartete Ausgabe lautet:

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

Aber zur Zeit eine Ausgabe wie unten Ich erhalte:

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

Bitte helfen Sie, ich habe versucht zu lösen es, aber gescheitert. Bitte markieren Sie es nicht doppelt, da ich bereits andere Antworten überprüft habe und überhaupt nicht geholfen habe.

Edit 1: Eingang grundsätzlich aus einem Wörterbuch dic deren Mapping-Typ ist <String, List> zum Beispiel genommen wird: "Reizung" => [1,3,5,7,8] wo Reizung der Schlüssel ist, und einer Liste von Seitenzahlen zugeordnet werden. Dies wird grundsätzlich in der äußeren for-Schleife gelesen, wobei key das Schlüsselwort und value eine Liste der Seiten des Auftretens dieses Schlüsselworts ist.

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

Wenn es sich um eine ordnungsgemäß erstellte 'json'-Datei handelt, können Sie das' json'-Modul verwenden, anstatt es als Text zu importieren. Können Sie Einzelheiten zu Ihrer Eingabedatei angeben? – asongtoruin

+0

Eingabe ist ein langer Prozess, ich werde die Antwort mit Abstraktion der Eingabe bearbeiten –

+1

Warum verwenden Sie nicht json.dump und aktualisieren Sie das JSON-Objekt als weitere Daten eintrifft? –

Antwort

6

Was @ andrea-f sieht mir gut, hier eine andere Lösung:

Fühlen Sie sich frei in beide :)

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 holen

Es ist die gleiche Idee, ich zuerst eine große json_dict erstellen, um direkt in JSON gespeichert werden. Ich verwende die with Anweisung die json speichern auch den Fang von exception

zu vermeiden, sollten Sie einen Blick auf das Dokument von json.dumps() haben, wenn Sie in Zukunft brauchen in Ihrer json Ausgabe zu verbessern.

EDIT

Und nur zum Spaß, wenn Sie tmp var nicht gefällt, können Sie in einem Einzeiler :)

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

Es gab könnten alle Daten for Schleife tun für die endgültige Lösung etwas nicht vollständig lesbar wie folgt aus:

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

Es sieht aus wie Sie wollen nicht Ihre json als die gewünschte Ausgabe speichern, aber sein abble zu es lesen.

In der Tat können Sie auch json.dumps() verwenden, um drucken Ihre JSON.

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

Es ist immer noch ein Problem hier aber "filename": am Ende der Liste gedruckt wird, weil die d von data vor den f kommt.

Um die Bestellung zu erzwingen, müssen Sie ein OrderedDict in der Generierung des Diktats verwenden. Achten Sie darauf, die Syntax ist hässlich (imo) mit python 2.X

Hier ist die neue Komplettlösung;)

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) 

Will Ausgang:

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

Aber seien Sie vorsichtig, die meiste Zeit, es ist besser, eine reguläre.json Datei zu speichern, um Quersprachen zu sein.

+1

Sie haben es Chef genagelt. –

2

Ihr aktueller Code funktioniert nicht, weil die Schleife durchläuft das vor-letztes Element der }, dann hinzuzufügen, wenn die Schleife läuft wieder setzt sie das Flag auf falsch, aber die Letztes Mal lief es ein , da es dachte, dass es ein anderes Element geben wird.

Wenn dies Ihr dict: a = {"bomber":[1,2,3,4,5]} dann können Sie tun:

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 

Dann speichern Sie die Daten von:

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

Es tut mir leid, aber bitte verstehe das Problem, ich lese keine JSON-Datei jeglicher Art, ich muss eine JSON-Ausgabe aus dem Wörterbuch ** Edit 1 ** erstellen und nicht nur die Ausgabe direkt formatiert so bald wie erwartet Ausgabe –

+0

@AsifAli können Sie die aktualisierte Antwort überprüfen? –

+0

Können Sie es bitte neu formatieren, wie in ** erwartete Ausgabe ** gezeigt. Ich probierte es aus und bekam verschiedene Fehler. Es wird hilfreich sein und ich werde die Antwort auch akzeptieren, danke für die Bemühungen –

Verwandte Themen