2014-07-02 83 views
0

對於模糊標題感到抱歉,我需要一些關於Python魔法的幫助,並且想不到任何更具描述性的內容。Python腳本將複雜的扁平化數據轉換爲JSON

我有一個固定的JSON數據結構,我需要將CSV文件轉換爲。該結構是固定的,但與列表等深層嵌套。它與此類似,但更復雜:

{ 
    "foo" : bar, 
    "baz" : qux, 
    "nub" : [ 
     { 
      "bub": "gob", 
      "nab": [ 
       { 
        "nip": "jus", 
        "the": "tip", 
       }, 
       ... 
      ], 
     }, 
     ... 
    ], 
    "cok": "hed" 
} 

希望你明白了。列表上的列表上的列表等等。我爲CSV可能是這樣的:

foo, baz, nub.bub, nub.nab.nip, nub.nab.the, cok 

bar, qux, "gob" ,,,, "hed" 

,,,,, "nab", "jus","tip",, 

,,,,, "nab", "other", "values",, 

很抱歉,如果這是很難讀,但其基本思想是,如果有這將是其下一行的上市項目,並重復的值來表示什麼子 - 列表屬於什麼。

我不想找任何人想出解決這個混亂的問題,只是可能有一些關於技術或事情的指針。

現在我有一個粗略的計劃:

我轉動頭部到包含密鑰元組的列表開始。對於每組行(項目),我將創建我的模板字典副本。我有一個函數,它將從一個鍵元組中設置一個字典值,除非它找到一個列表。在這種情況下,我將調用一個時髦的遞歸函數並將其傳遞給我的迭代器,並繼續填充該函數中的dict,並在發現新列表時進行遞歸調用。

我也可以做很多硬編碼,但是有什麼好玩的呢?

這就是我的故事。再次,只是尋找一些關於如何做到這一點的最佳方法的指針。我寫得很快,所以它可能有點混亂,請讓我知道,如果有更多的信息會有所幫助。謝謝!

+0

有問題的格式基本上是不同的,試圖解析一個到另一個將證明兩個問題,並容易出錯。 _爲什麼你需要這樣的csv文件? –

+0

有人爲我製作測試數據集,這是他們使用的格式。這並不理想,但我不想讓他們改變它(他們正在用手做這件事......)。我可以解析它,這隻會是一個痛苦的屁股。 – user3779812

回答

1

您的JSON格式錯誤。另外,你的json不能包含數組以實現你想要的。

def _tocsv(obj, base=''): 
    flat_dict = {} 
    for k in obj: 
     value = obj[k] 
     if isinstance(value, dict): 
      flat_dict.update(_tocsv(value, base + k + '.')) 
     elif isinstance(value, (int, long, str, unicode, float, bool)): 
      flat_dict[base + k] = value 
     else: 
      raise ValueError("Can't serialize value of type "+ type(value).__name__) 
    return flat_dict 

def tocsv(json_content): 
    #assume you imported json 
    value = json.loads(json_content) 
    if isinstance(value, dict): 
     return _tocsv(value) 
    else: 
     raise ValueError("JSON root object must be a hash") 

會讓你變平是這樣的:

{ 
    foo: "nestor", 
    bar: "kirchner", 
    baz: { 
     clorch: 1, 
     narf: 2, 
     peep: { 
      ooo: "you suck" 
     } 
    } 
} 

成類似:

{"foo": "nestor", "bar": "kirchner", "baz.clorch": 1, "baz.narf": 2, "baz.peep.ooo": "you suck"} 

密鑰不保存任何特定的順序。如果你想保持秩序,你可以用0123代替flat_dict = {}來構建OrderedDict。

假設你有這樣的平板類型的字典的數組:

def tocsv_many(json_str): 
    #assume you imported json 
    value = json.loads(json_content) 
    result = [] 
    if isinstance(value, list): 
     for element in value: 
      if isinstance(element, dict): 
       result.append(_tocsv(element)) 
      else: 
       raise ValueError("root children must be dicts") 
    else: 
     raise ValueError("The JSON root must be a list") 
flat_dicts = tocsv_many(yourJsonInput) 

,你可以:

  1. 創建csvlines = []名單將舉行烏拉圭回合文件中的CSV行。
  2. 創建一個keysSet = set()它將保存可能的密鑰。
  3. 對於您以這種方式獲得的每個字典,請將.keys()添加到集合中。沒有按鍵順序保證正常設置;改爲使用有序集。最後我們得到第一個CSV行。

    for flat_dict in flat_dicts: 
        keysSet.extend(flat_dict.keys()) 
    csvlines.appens(",".join(keysSet)) 
    
  4. 每個字典你已經(再次循環),您生成一個這樣的數組:

    for flat_dict in flat_dicts: 
        csvline = ",".join([json.dumps(flat_dict.get(keyInSet, '')) for keyInSet in keysSet]) 
        csvlines.append(csvline) 
    
  5. voilah!你有你的線csvlines

+0

感謝您的回答!不幸的是,我要從csv開始。我無法控制任何一種數據格式,這正是我必須使用的。我可能只是要硬編碼很多東西來挽救我自己的頭痛。 – user3779812

+0

如果你來自csv,它更容易。存儲第一行並用逗號將它們分解爲鍵。對於後面的每一行:用逗號分隔它,用鍵()將它分開,迭代並通過迭代創建一個json結構(並通過按點分隔鍵) –