2017-07-02 30 views
0

的列表中刪除角色,我有麻煩遞歸地從裏面類型的字典列表蟒蛇字典的鍵刪除不想要的字符。我試圖通過使用不需要我硬編碼在代碼中所有領域的遞歸解決方案,從所有數據集中的刪除「#」和「@」標誌。的Python(2.X) - 從鍵類型的字典

{ 
    "id": "123456", 
    "name": "some name", 
    "contact_info": { 
     "phone": { "@suppress": "false", "#number": "123456789" } 
    }, 
    "categories": { 
     "category ": [ 
      { "@primary ": "true", "@parentid ": "1234", "@nameid ": "5678", "@name ": "Category name 1" }, 
      { "@primary ": "false", "@parentid ": "5678", "@nameid ": "2532", "@name ": "Category name 2" } 
     ] 
    } 
} 

這裏是我到目前爲止,可以應付類型的字典中使用的代碼,但我有對付類型的字典列表的問題(項目:類)。

import json 

def remove_chars(obj): 
     for key in obj.keys(): 
       if isinstance(obj[key], dict): 
         obj[key] = remove_chars(obj[key]) 
       new_key = key.replace("@","").replace("#","") 
       if new_key != key: 
         obj[new_key] = obj[key] 
         del obj[key] 
     return obj 

a = json.loads('{ "id": "123456", "name": "some name", "contact_info": { "phone": { "@suppress": "false", "#number": "123456789" } }, "categories": { "category ": [ { "@primary ": "true", "@parentid ": "1234", "@nameid ": "5678", "@name ": "Category name 1" }, { "@primary ": "false", "@parentid ": "5678", "@nameid ": "2532", "@name ": "Category name 2" } ] } }') 

print a 
print remove_chars(a) 

這裏是各自的輸出: 第一個是好的,因爲它消除來自第一字典的@和#跡象。但列表下的那些處理不正確。

{u'contact_info': {u'phone': {u'@suppress': u'false', u'#number': u'123456789'}}, u'id': u'123456', u'categories': {u'category ': [{u'@parentid ': u'1234', u'@name ': u'Category name 1', u'@nameid ': u'5678', u'@primary ': u'true'}, {u'@parentid ': u'5678', u'@name ': u'Category name 2', u'@nameid ': u'2532', u'@primary ': u'false'}]}, u'name': u'some name'} 

{u'contact_info': {u'phone': {u'suppress': u'false', u'number': u'123456789'}}, u'id': u'123456', u'categories': {u'category ': [{u'@parentid ': u'1234', u'@name ': u'Category name 1', u'@nameid ': u'5678', u'@primary ': u'true'}, {u'@parentid ': u'5678', u'@name ': u'Category name 2', u'@nameid ': u'2532', u'@primary ': u'false'}]}, u'name': u'some name'} 
+0

到目前爲止,您嘗試了哪些方法?您卡在哪裏? – zwer

+1

如果您正在尋找調試幫助,請提供[最小的,完整的,和可覈查的示例](http://stackoverflow.com/help/mcve) –

+0

你告訴我你的解決方案,我會告訴你我的。 –

回答

1

如果您不希望更改在原地發生,則這是直接的方法。它只是蠻力遍歷數據結構,使得關於它包含的內容相當剛性的假設:

>>> def replace_keys(data, replacer): 
...  if isinstance(data, dict): 
...   return {replacer(k): replace_keys(v, replacer) for k, v in data.items()} 
...  elif isinstance(data, list): 
...   return [replace_keys(val, replacer) for val in data] 
...  else: 
...   return data 
... 
>>> def replacer(s): 
... return s.translate({35: '', 64: ''}) 
... 
>>> from pprint import pprint 
>>> pprint(data) 
{'categories': {'category ': [{'@name ': 'Category name 1', 
           '@nameid ': '5678', 
           '@parentid ': '1234', 
           '@primary ': 'true'}, 
           {'@name ': 'Category name 2', 
           '@nameid ': '2532', 
           '@parentid ': '5678', 
           '@primary ': 'false'}]}, 
'contact_info': {'phone': {'#number': '123456789', '@suppress': 'false'}}, 
'id': '123456', 
'name': 'some name'} 
>>> pprint(replace_keys(data, replacer)) 
{'categories': {'category ': [{'name ': 'Category name 1', 
           'nameid ': '5678', 
           'parentid ': '1234', 
           'primary ': 'true'}, 
           {'name ': 'Category name 2', 
           'nameid ': '2532', 
           'parentid ': '5678', 
           'primary ': 'false'}]}, 
'contact_info': {'phone': {'number': '123456789', 'suppress': 'false'}}, 
'id': '123456', 
'name': 'some name'} 

同樣,這將創建自己的原始數據結構,它不被突變的副本。這樣做會更顯得煩人。

以上假設你的鑰匙總是字符串。此外,此功能可能有損耗,這是您的操作固有的。如果兩個不同的密鑰以某種方式映射到相同的新密鑰,則由於字典的性質,只保留一個密鑰。

+0

我在2.7.5下的翻譯功能遇到問題。我不斷收到TypeError。 '類型錯誤:預期的字符緩衝區object' 試圖'回報s.replace(無, '@#')'也不管用。 – Prashant

+0

@PrashantChaudhary然後,您可以簡單地使用'return s.replace('#','').replace('@','')'。請注意,'replacer'可以是任何你想要的一個字符串並返回一個替換。 –

+0

謝謝@ juanpa.arrivillaga ...解決方案。雖然爲每個處理過的記錄創建一個副本似乎代價很高,但對我來說這很有效,因爲我一次處理5K條記錄,系統可以處理它。 – Prashant