2017-07-01 83 views
3

我試圖在Python中查找嵌套字典中的所有數據屬性。一些對象在其關鍵定義中可能有多個級別。我怎樣才能找到這樣一個複雜的嵌套數據的頭(如果我們認爲是一個表結構)。這裏是我的數據非常少行,看看它的樣子:在嵌套字典中查找鍵的所有鍵和鍵

{"MessageType": "SALES.HOLDCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTZVVWZWbCnA==", "RefInfo": {"TId": {"Id": "ZMKXwpbClsOhwpNiw5E="}, "UserId": {"Id": "wpzCksKWwpbCpMKTYsKeZMKZbA=="}, "SentUtc": "2013-04-28T16:59:48.6698042", "Source": 1}, "ItemId": {"Id": 116228}, "Quantity": 1, "ExpirationDate": "2013-04-29T", "Description": null}} 
{"MessageType": "SALES.SALEITEMCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTwp3CiFZkZMKWwpfCpMKZ", "RefInfo": {"TId": {"Id": "ZGA="}, "UserId": {"Id": "ZMKj"}, "SentUtc": "2013-01-04T", "Source": 1}, "Code": {"Code": "074108235206"}, "Sku": {"Sku": "Con CS54"}}} 
{"MessageType": "SALES.SALEITEMCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTZcKHVsKcwpjClsKXwqTCmQ==", "RefInfo": {"TId": {"Id": "ZGA="}, "UserId": {"Id": "ZMKj"}, "SentUtc": "2013-01-04T", "Source": 1}, "Code": {"Code": "4000000021"}, "Sku": {"Sku": "NFL-Wallet-MK-2201"}}} 

由於該數據是JSON格式第一,我改變了格式,並試圖找到問題的關鍵:

import json 

data = [] 
with open("data.raw", "r") as f: 
    for line in f: 
     data.append(json.loads(line)) 

for lines in data: 
    print(lines.keys()) 

但爲所有行提供dict_keys(['Event', 'MessageType'])。 我需要(這個數據,我附後)就像一個列表:

'MessageType' 'Event_Id' 'Event_RefInfo_TId_Id' 'Event_RefInfo_UserId_Id' 'Event_RefInfo_SentUtc' 'Event_RefInfo_Source' 'Event_ItemId_Id' 'Event_ItemId_Quantity' 'Event_ItemId_ExpirationDate'  ... 

數據量非常大,我只需要找出哪些屬性做我有。

回答

1

你需要遍歷嵌套的字典,你現在的方法只能得到根字典的鍵。

您可以使用下面的生成函數遞歸找到鑰匙並遍歷嵌套類型的字典:

import json 
from pprint import pprint 

def find_keys(dct): 
    for k, v in dct.items(): 
     if isinstance(v, dict): 
      # traverse nested dict 
      for x in find_keys(v): 
       yield "{}_{}".format(k, x) 
     else: 
      yield k 

鑑於詞典列表從您的JSON對象派生,你可以找到在每個字典的關鍵,並把他們在一組這樣的條目是唯一的:

s = set() 
for d in json.loads(lst): 
    s.update(find_keys(d)) 

pprint(s) 

set(['Event_Code_Code', 
    'Event_Description', 
    'Event_ExpirationDate', 
    'Event_Id', 
    'Event_ItemId_Id', 
    'Event_Quantity', 
    'Event_RefInfo_SentUtc', 
    'Event_RefInfo_Source', 
    'Event_RefInfo_TId_Id', 
    'Event_RefInfo_UserId_Id', 
    'Event_Sku_Sku', 
    'MessageType']) 
+0

太謝謝你了。這個功能完美運作。這是一個問題...當我將這種方法應用於數據大小時,我可以將它讀入我的記憶中。當我想要處理大數據時,新問題就出現了。 – Mina

+0

因爲我必須使用readlines()來定義字符串列表,儘管我在打開文件時定義了緩衝大小,但它讀取整個文件(而不是唯一的緩衝區大小)。我如何才能讀取我在開放函數中以緩衝大小定義的那部分數據? – Mina