2017-01-03 1 views
0

Ich habe versucht, für diese spezielle Frage mit den Schlüsselwörtern in der Frage, aber konnte keine gute Lösung herausfinden.Python - Kombinieren n verschiedene JSON-Dateien/Wörterbücher (n könnte variieren)

sagen, dass ich eine Liste von JSON-Dateien haben (lässt die oberste Ebene übernehmen wird immer ein Wörterbuch sein):

"../data/Flickr_EXIF_0.json", 
"../data/Flickr_EXIF_150.json", 
"../data/Flickr_EXIF_300.json", 
"../data/Flickr_EXIF_450.json", 

Die Frage zu kombinieren, ist/verschmelzen alle JSON-Dateien in einer einzigen Datei.

Es ist natürlich einfach sein würde, das zu tun gegeben wir wissen, wie viele JSON Dateien, die wir wie verschmelzen,

with open("../data/Flickr_EXIF_0.json", "r") as jFl: 
    obj1 = json.load(jFl) 

with open("../data/Flickr_EXIF_150.json", "r") as jFl: 
    obj2 = json.load(jFl) 

with open("../data/Flickr_EXIF_300.json", "r") as jFl: 
    obj3 = json.load(jFl) 

with open("../data/Flickr_EXIF_450.json", "r") as jFl: 
    obj4 = json.load(jFl) 

d = {**obj1, **obj2, **obj3, **obj4} 

Aber wie würden Sie eine Funktion sagen schreiben, die eine unbekannte Anzahl von JSONs kombinieren . Ich suche eine pythonische Lösung.

Dies ist meine Teillösung, die einen Fehler wirft:

def appendJSON(*inpFl): 
    flObjs = [] 
    for fl in inpFl: 
     with open(fl, "r") as jFl: 
      flObjs.append(json.load(jFl)) 

    # something smart here! 
    itemsList = [list(objs.items()) for objs in flObjs] 

    return dict(itemsList) 

Fehler:

ValueError Traceback (most recent call last) in() 20 "../data/Flickr_EXIF_1350.json", 21 "../data/Flickr_EXIF_1500.json", ---> 22 "../data/Flickr_EXIF_1650.json")

in appendJSON(*inpFl) 7 itemsList = [objs.items() for objs in flObjs] 8 ----> 9 return dict(itemsList) 10 11 objs = appendJSON("../data/Flickr_EXIF_0.json",

ValueError: dictionary update sequence element #0 has length 150; 2 is required

Beispiel Debug-Werte für itemsList:

[[('5822864395', 
    {'date': '2010-06-10 14:48:25', 
    'height': 2592, 
    'lat': 0.0, 
    'long': 0.0, 
    'orientation': 0, 
    'width': 2818}), 
    ('1458886548', 
    {'date': '2007-09-22 02:59:20', 
    'height': 768, 
    'lat': 39.145372, 
    'long': -84.508981, 
    'orientation': 0, 
    'width': 1024})]] 

Alternative Lösung,

def appendJSON(*inpFl): 
    flObjs = [] 
    for fl in inpFl: 
     with open(fl, "r") as jFl: 
      flObjs.append(json.load(jFl)) 

    for i in range(1,len(flObjs)): 
     flObjs[0].update(flObjs[i]) 

    return flObjs[0] 
+0

werden Sie den Fehler mit uns teilen? –

+0

Oh sicher. Das tut mir leid! @DanFarrell –

+1

Danke. Warum versuchst du, eine Liste von Diktaten in ein Diktat umzuwandeln? Wie erwartest du, dass das genau funktioniert? –

Antwort

2

Ich würde zuerst eine generische Lösung machen, dann optional optimieren, wenn die Typen der obersten Ebenen der JSON-Datei alle gleich sind (d. H. all object/dict oder alle array/list).

Wenn Sie nach dem Laden eine Mischung aus Top-Level-Typen haben (dict, list, value), können Sie diese sowieso nicht kombinieren. Sie können sie nur kombinieren, wenn es sich bei allen geladenen Daten um ein Diktat handelt oder jede geladene eine Liste ist. Wenn Sie eine Kombination haben oder wenn Sie einen oder mehrere Werte im Toplevel haben, können Sie nicht kombinieren.

Der generische Ansatz ist eine leere Liste und .append() die Daten von json.load() es geladen zu haben, zu erstellen, während Spur zu halten hat, dict, Liste oder Werte:

def combine(json_file_names): 
    combined = [] 
    have_dict = False 
    have_list = False 
    for file_name in json_file_names: 
     data = json.load(file_name) 
     combined.append(data) 
     if isinstance(data, dict): 
      have_dict = True 
     elif isinstance(data, list): 
      have_list = True 
     else: 
      have_list = have_dict = True 

    # if have_list and have_dict have the same value, either there is nothing 
    # loaded or it's a mixed bag. In both cases you can't do anything 
    if have_list == have_dict: 
     return combined 
    if have_list: 
     tmp = [] 
     for elem in combined: 
      tmp.extend(elem) 
    else: # have_dict 
     tmp = {} 
     for elem in combined: 
      tmp.update(elem) 
    return tmp 

Bitte beachten Sie, dass beim Kämmen Nur- top-level-dicts überschreiben Schlüssel-Wert-Paare aus vorherigen geladenen Daten.

0

Da json einfach in Python dict konvertierbar ist, müssen Sie nur alle json-Dateien in Wörterbücher einlesen, alle Wörterbücher zusammenführen, in json konvertieren und in einer Datei speichern.

+1

Dies könnte ein Kommentar sein. –

+1

Wenn Sie eine Liste als JSON-Datei ('json.dump ([1, 2, 3])') speichern, wie werden Sie das dann einfach in ein Diktat konvertieren? Ordnen Sie die Liste einfach einem zufälligen Schlüsselwert zu? – Anthon