2017-07-01 8 views
3

私はPythonの入れ子になった辞書の中のデータのすべての属性を見つけようとしています。オブジェクトの中には、キー定義に複数のレベルがあるものがあります。このような複雑なネストされたデータのヘッダを(テーブル構造と考えるなら)どのように見つけることができますか?このデータは、最初に私はフォーマットを変更し、キーを見つけることを試みたJSON形式であるので入れ子になっている辞書のキーのすべてのキーとキーを見つける

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

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

ネストされたdictsをトラバースする必要があります。現在の方法は、ルート辞書のキーまでしか取得できません。

あなたは鍵を見つけて、再帰的にネストされたdictsを横断する次のジェネレータ機能を使用することができます。

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オブジェクトから派生して辞書のリストを考えると、あなたはそれぞれのdictのキーを見つけて置くことができますそれらのエントリが一意であるように、セットの中:

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

関連する問題