2015-05-26 8 views
5

यह सिर्फ इतना है कि कोई सामान्य जवाब शीर्ष पर बुलबुला नहीं है।विशिष्ट कुंजी के गतिशील पायथन शब्दकोश को कैसे साफ़ करें?

उपकरण की प्रकृति मैं निर्देशों पर काम कर रहा हूं, हम लगभग 25 विभिन्न उपकरणों के लिए 'सेटिंग' स्टोर करने के लिए मोंगोडीबी का उपयोग करते हैं। प्रत्येक टूल में इसकी अपनी सेटिंग्स स्कीमा होती है, इसलिए प्रत्येक दस्तावेज़ अलग होता है, लेकिन वे सभी एक ही संग्रह में संग्रहीत होते हैं और उसी संपादन पृष्ठ पर संपादित होते हैं जो जेसन स्कीमा द्वारा खींचा जाता है।

शब्दकोश की स्कीमा को नहीं जानते, मैं डेटा को पुन: सक्रिय और स्वच्छ करने के तरीके को समझने के लिए संघर्ष कर रहा हूं, विशेष रूप से पासवर्ड को हटा रहा हूं।

निम्नलिखित शब्दकोश को देखते हुए, और जानते हुए भी अन्य dicts अलग स्कीमा हो सकता है, मैं कैसे dict में हर आइटम को पार और एक प्रति बना सकते हैं, समान किसी भी कुंजी == "पासवर्ड" के साथ छोड़कर हटा दिया?

तो:

{ 
    "_enabled": true, 
    "instances": [ 
    { 
     "isdefault": true, 
     "name": "dev", 
     "password": "abc123", 
     "url": "http://dev.example.com", 
     "user": "buffy" 
    }, 
    { 
     "isdefault": false, 
     "name": "prod", 
     "password": "xxxxx", 
     "url": "http://prod.example.com", 
     "user": "spike" 
    }, 
    { 
     "isdefault": false, 
     "name": "qa", 
     "password": "dasddf", 
     "url": "http://prod.example.com", 
     "user": "willow" 
    } 
    ], 
    "label": "MyServers" 
} 

परिणाम चाहिए में:

{ 
    "_enabled": true, 
    "instances": [ 
    { 
     "isdefault": true, 
     "name": "dev", 
     "url": "http://dev.example.com", 
     "user": "buffy" 
    }, 
    { 
     "isdefault": false, 
     "name": "prod", 
     "url": "http://prod.example.com", 
     "user": "spike" 
    }, 
    { 
     "isdefault": false, 
     "name": "qa", 
     "url": "http://prod.example.com", 
     "user": "willow" 
    } 
    ], 
    "label": "MyServers" 
} 
+3

है शब्दकोश प्रविष्टियों जहां फंस रहे हैं से महत्वपूर्ण मूल्य जोड़े निकालना चाहते हैं ? आपने क्या प्रयास किया ऐसा लगता है कि आपको बस उदाहरणों में डिक्ट्स पर लूप करना होगा और पासवर्ड कुंजी/मूल्य जोड़ी हटाएं ... – aschmid00

+0

एक सेकंड प्रतीक्षा करें, क्या यह एक अजगर शब्दकोश भी है? यह जेसन या कुछ और जैसा दिखता है ... – Zizouz212

+0

हाँ यह मुझे जेसन की तरह दिखता है – aschmid00

उत्तर

3

dict deepcopy पहले, तो सभी शब्दकोशों पकड़ने और पासवर्ड कुंजियां निकालें:

from copy import deepcopy 

def remove_pass(v): 
    if isinstance(v, dict): 
     if "password" in v: 
      del v["password"] 
     for ele in v.values(): 
      remove_pass(ele) 
    elif isinstance(v, Iterable) and not isinstance(v, basestring): 
     for ele in v: 
      remove_pass(ele) 


from pprint import pprint as pp 
d = deepcopy(d) 
for v in d.values(): 
    remove_pass(v) 

इनपुट:

{'_enabled': 'true', 
'foo': {'isdefault': 'false', 
     'name': 'qa', 
     'nested': {'password': 'nested'}, 
     'password': 'dasddf', 
     'url': 'http://prod.example.com', 
     'user': 'willow'}, 
'instances': [{'isdefault': 'true', 
       'name': 'dev', 
       'password': 'abc123', 
       'url': 'http://dev.example.com', 
       'user': 'buffy'}, 
       {'isdefault': 'false', 
       'name': 'prod', 
       nested': {'more_nesting': {'even_more_nesting': ({'password': 'foobar'}, 
             {'password': 'foob'}), 
             'password': 'bar'}, 
       'password': 'xxxxx', 
       'url': 'http://prod.example.com', 
       'user': 'spike'}, 
       {'isdefault': 'false', 
       'name': 'qa', 
       'password': 'dasddf', 
       'url': 'http://prod.example.com', 
       'user': 'willow'}], 
'label': 'MyServers'} 

आउटपुट:

{'_enabled': 'true', 
'foo': {'isdefault': 'false', 
     'name': 'qa', 
     'nested': {}, 
     'url': 'http://prod.example.com', 
     'user': 'willow'}, 
'instances': [{'isdefault': 'true', 
       'name': 'dev', 
       'url': 'http://dev.example.com', 
       'user': 'buffy'}, 
       {'isdefault': 'false', 
       'name': 'prod', 
       'nested': {'more_nesting': {'even_more_nesting': ({}, {})}}, 
       'url': 'http://prod.example.com', 
       'user': 'spike'}, 
       {'isdefault': 'false', 
       'name': 'qa', 
       'url': 'http://prod.example.com', 
       'user': 'willow'}], 
'label': 'MyServers'} 
+0

यदि पासवर्ड में' पासवर्ड 'है तो यह देखने से भी आसान है और फिर उस कुंजी/मान जोड़ी को हटा देना 'd.pop ('पासवर्ड', कोई नहीं)' – bgporter

+0

@bgporter, एक लुकअप 0 (1) है, वास्तव में कोई समस्या नहीं है –

+0

निष्पादन समय भी नहीं, कोड की स्पष्टता भी सोचना। स्वाद का मामला, मुझे लगता है। – bgporter

0

आप अपने डेटा (यानी, एक सरणी/शब्दकोश किस गहराई में "पासवर्ड" कुंजी उम्मीद करना) में से प्रत्येक की संरचना को पता था, तो यह आसान होगा। "पासवर्ड" कुंजी खोजने के लिए आपको बस अपनी सूची वस्तुओं और शब्दकोशों के माध्यम से लूप की आवश्यकता होगी।

यदि प्रत्येक सेटिंग शब्दकोश की संरचना वास्तव में अप्रत्याशित है, तो आपको एक समाधान को एक साथ जोड़ना होगा। इस तरह के मामलों में मैंने जो किया है, वह मेरे JSON को एक स्ट्रिंग पर डंप कर रहा है, जिस डेटा में दिलचस्पी है उसे निकालने/अलग करने के लिए रेगेक्स का उपयोग करें और फिर स्ट्रिंग को संरचित JSON पर लोड करें।

कुछ इस तरह:

आयात json, में फिर

raw_data = """{ 
    "_enabled": true, 
    "instances": [ 
    { 
     "isdefault": true, 
     "name": "dev", 
     "password": "abc123", 
     "url": "http://dev.example.com", 
     "user": "buffy" 
    }, 
    { 
     "isdefault": false, 
     "name": "prod", 
     "password": "xxxxx", 
     "url": "http://prod.example.com", 
     "user": "spike" 
    }, 
    { 
     "isdefault": false, 
     "name": "qa", 
     "password": "dasddf", 
     "url": "http://prod.example.com", 
     "user": "willow" 
    } 
    ], 
    "label": "MyServers" 
}""" 

# I load and then dump my raw_data just to iron out any inconsistencies 
# in formatting before applying regex. i.e., inconsistent use of " instead of ' 
structured_data = json.loads(raw_data) 
dumped_data = json.dumps(structured_data) 

scrubbed = re.sub(r'"password": ".*?",', '', dumped_data) 
structured_scrubbed = json.loads(scrubbed) 

परिणाम:

structured_scrubbed = {'_enabled': True, 
'instances': [{'isdefault': True, 
       'name': 'dev', 
       'url': 'http://dev.example.com', 
       'user': 'buffy'}, 
       {'isdefault': False, 
       'name': 'prod', 
       'url': 'http://prod.example.com', 
       'user': 'spike'}, 
       {'isdefault': False, 
       'name': 'qa', 
       'url': 'http://prod.example.com', 
       'user': 'willow'}], 
'label': 'MyServers'} 
0

मैं एक सामान्य समारोह getPaths का उपयोग एक नेस्टेड में एक विशिष्ट कुंजी के रास्ते खोजने के लिए शब्दकोश। आप आगे बढ़ने के लिए इसका उपयोग कर सकते हैं और अपने "पासवर्ड" कुंजी पर सभी पथ ढूंढ सकते हैं और फिर इसे बदल सकते हैं, या इसे हटा सकते हैं। यह जेसन स्ट्रिंग के सभी प्रारूप/स्कीमा के लिए काम करता है।

def getPaths(dictionary, searchKey): 
    ''' 
    generator to get all paths for the key in the nested dictionary 

    ''' 
    for k, v in dictionary.items(): 
     if k == searchKey : 
      yield [] 
     elif isinstance(v, dict): 
      # if the value if dict, go in recursively and yield the path 
      for subkey in getPaths(v, searchKey): 
       yield [k]+subkey 
     elif isinstance(v, list): 
      # if value is a list, for each element in the list, go in recursively and yield the path 
      for i, item in enumerate(v): 
       if isinstance(item, dict): 
        for subkey in getPaths(item, searchKey): 
         yield [k]+[i]+subkey 


jsonstring = """{ 
    "_enabled": true, 
    "instances": [ 
    { 
     "isdefault": true, 
     "name": "dev", 
     "password": "abc123", 
     "url": "http://dev.example.com", 
     "user": "buffy" 
    }, 
    { 
     "isdefault": false, 
     "name": "prod", 
     "password": "xxxxx", 
     "url": "http://prod.example.com", 
     "user": "spike" 
    }, 
    { 
     "instance2": { 
         "isdefault": false, 
         "name": "qa", 
         "password": "dasddf", 
         "url": "http://prod.example.com", 
         "user": "willow" 
         } 
    } 
    ], 
    "label": "MyServers" 
}""" 
import json 
jsonObj = json.loads(jsonstring) 


paths = getPaths(jsonObj , "password") 
for path in paths: 
    print('path:', path) 

परिणाम:

>>> path: ['instances', 0] 
>>> path: ['instances', 1] 
>>> path: ['instances', 2, 'instance2'] 
0

मान लिया जाये कि आप केवल कंटेनर जो सूची या शब्दकोशों हैं की जाँच करें और जो key = "password"

#first copy the structure 
new_data = copy.deepcopy(data) 

#this is a recursive function. 
#Heavily nested structures may fail due to recursion limit 
def clean_hierarchy(ele): 
    #lists may contain dictionaries, so clean theses entries 
    if isinstance(ele,list): 
     for val in ele: 
      clean_hierarchy(val) 
    if isinstance(ele,dict): 
     #remove possible password entry 
     if "password" in ele: 
      ele.pop("password",None) 
     #dictionary may contain more dictionaries. Rinse and repeat! 
     for val in ele.values(): 
      clean_hierarchy(val) 

clean_hierarchy(new_data) 
संबंधित मुद्दे