2016-07-01 8 views
0

ich ein JSON-Objekt haben, die wie folgt lautet:JSON Formatierung durch Anhängen dict Werte zur Liste

{ "produktNr:"1234", 
    "artNr_01":"12", 
    "artNr_02":"23", 
    "artNr_03":"", 
    "artNr_04":"14", 
    "name_01":"abc", 
    "name_02":"der", 
    "test":"junk" 
} 

Ich möchte dies wie folgt in ein Wörterbuch konvertieren:

{ "produktNr:"1234", "artNr":["12","23","","14"], "name":["abc","der"], "test":"junk"} 

Diese Umwandlung ist basierend auf einer gegebenen Sequenz, beispielsweise seq = ["artNr","name"]. Daher wird der Inhalt der Sequenz in den Schlüsseln des Wörterbuchs gesucht und die Werte in einer Liste gesammelt.

Mein Versuch so weit:

tempDict = {} 
for key,value in fmData.iteritems(): 
    for seqval in seq: 
     if seqval in key: 
      if seqval in tempDict: 
       tempDict[seqval].append(value) 
      else: 
       x = [] 
       x.append(value) 
       tempDict[seqval]=x 
     else: 
      tempDict[key] = value 

ein paar Probleme Gesichter.

  • Die Liste der Werte sind nicht also bestellt, "artNr":["","14","12","23"] statt Werte von [_01,_02,_03,_04]

  • Die Elemente können nicht die Wörterbuchelemente in resultierenden nicht gelöscht werden kann aus dem Wörterbuch, da in der Schleife geknallt werden:

    {"ProduktNr:" 1234 "," artNr ": [" 12 "," 23 "," "," 14 "]," artNr_01 ":" 12 "," artNr_02 ":" 23 "," artNr_03 ":" "," artNr_04 ":" 14 "," name ": [" abc "," der "]," name_01 ":" abc "," name_02 ":" der "," test ":" junk " }

Würde gerne verstehen, wie man damit umgeht, vor allem, wenn es einen pythonischen Weg gibt, um dieses Problem zu lösen.

Antwort

1

Sie OrderedDict vom collections Paket verwenden:

from collections import OrderedDict 
import re 

input_dict = { "produktNr":"1234", 
       "artNr_01":"12", 
       "artNr_02":"23", 
       "artNr_03":"", 
       "artNr_04":"14", 
       "name_01":"abc", 
       "name_02":"der", 
       "test":"junk" } 

# split keys on the first '_' 
m = re.compile('^([^_]*)_(.*)') 

def _order_by(item): 
    # helper function for ordering the dict. 
    # item is split on first '_' and, if it was successful 
    # the second part is returned otherwise item is returned 
    # if key is something like artNr_42, return 42 
    # if key is something like test, return test 
    k,s = item 
    try: 
     return m.search(k).group(2) 
    except: 
     return k 

# create ordered dict using helper function 
orderedDict = OrderedDict(sorted(input_dict.items(), key=_order_by)) 

aggregated_dict = {} 
for k, v in orderedDict.iteritems(): 
    # split key 
    match = m.search(k) 

    if match: 
     # key is splittable, i.e., key is something like artNr_42 
     kk = match.group(1) 
     if kk not in aggregated_dict: 
      # create list and add value 
      aggregated_dict[kk] = [v] 
     else: 
      # add value 
      aggregated_dict[kk].append(v) 
    else: 
     # key is not splittable, i.e., key is something like produktNr 
     aggregated_dict[k] = v 

print(aggregated_dict) 

die

die gewünschte Ausgabe gibt
{'produktNr': '1234', 'test': 'junk', 'name': ['abc', 'der'], 'artNr': ['12', '23', '', '14']} 
+0

Das ist absolut schön @desiato .. Vielen Dank. Ich habe sehr viel von diesem Code gelernt: mit Schlüsseln sortiert, re.search verwenden und kompilieren. – Mellkor

0

Sie können ein neues Wörterbuch erstellen, die in einer Liste mit '_' in den Tasten Gruppenwerte von Tasten, während die anderen Schlüssel und Werte intakt gehalten werden. Dies sollte tun:

d = { "produktNr":"1234", "artNr_01":"12", "artNr_02":"23","artNr_03":"","artNr_04":"14","name_01":"abc","name_02":"der","test":"junk"} 
new_d= {} 
for k, v in d.items(): 
    k_new = k.split('_')[0] 
    if '_' in k: 
     if k_new not in new_d: 
      new_d[k_new] = [v] 
     else: 
      new_d[k_new].append(v) 
    else: 
     new_d[k_new] = v 
print(new_d) 
# {'artNr': ['', '14', '23', '12'], 'test': 'junk', 'produktNr': '1234', 'name': ['der', 'abc']} 

Dicts unordered Sammlungen sind, so mit welcher Reihenfolge die Werte an die Liste angehängt sind, werden unbestimmt.

+0

Vielen Dank @Moses .. Ist es irgendwie möglich, es bestellt zu haben? – Mellkor

+0

Wenn Sie ein 'OrderedDict' für beide Wörterbücher verwenden. Wenn der Auftrag ein Muster hat, können Sie das Sortieren mit "sortiert" betrachten –

0

Eine leichte Modifikation des Codes:

tempDict = {} 
for key,value in fmData.iteritems(): 
    seqval_in_key = "no" 
    for seqval in seq: 
     if seqval in key: 
      seqval_in_key = "yes" 
    for seqval in seq: 
     if seqval in key: 
      if seqval in tempDict: 
       tempDict[seqval].append(value) 
      else: 
       x = [] 
       x.append(value) 
       tempDict[seqval]=x 
     else: 
      if (seqval_in_key == "no"): 
       tempDict[key] = value 
print tempDict 

Ergebnis:

{'produktNr': '1234', 'test': 'junk', 'name': ['abc', 'der'], 'artNr': ['14', '23', '', '12']}