2010-11-19 6 views
8

मेरे पास एक ऐसा निर्देश है जिसे मैं जेएसओएन में सरलजसन का उपयोग करके परिवर्तित करना चाहता हूं।यह सुनिश्चित करने के लिए कि एक पायथन dict कुंजी लोअरकेस हैं?

मैं कैसे सुनिश्चित कर सकता हूं कि मेरे निर्देश की सभी चाबियाँ लोअरकेस हैं?

{ 
     "DISTANCE": 17.059918745802999, 
     "name": "Foo Bar", 
     "Restaurant": { 
      "name": "Foo Bar", 
      "full_address": { 
       "country": "France", 
       "street": "Foo Bar", 
       "zip_code": "68190", 
       "city": "UNGERSHEIM" 
      }, 
      "phone": "+33.389624300", 
      "longitude": "7.3064454", 
      "latitude": "47.8769091", 
      "id": "538" 
     }, 
     "price": "", 
     "composition": "", 
     "profils": {}, 
     "type_menu": "", 
     "ID": "" 
    }, 

संपादित करें: धन्यवाद, मेरे प्रश्न पर एक नज़र डालने के लिए धन्यवाद, मुझे खेद है कि मैंने विस्तार से यह समझाया नहीं कि मैं यह क्यों चाहता था। django-piston के JSONEmitter को पैच करना था।

+2

सुनिश्चित करने के लिए वे लोअरकेस वे लोअरकेस होना चाहिए रहे हैं। लोअरकेस कुंजी के साथ एक नियम बनाएँ। –

+0

"सुनिश्चित करें" से आपका क्या मतलब है? क्या आपके पास और मौजूदा नियम है और क्या आप यह जांचना चाहते हैं कि सभी चाबियाँ लोअरकेस हैं या नहीं? या उन्हें सभी को लोअरकेस में परिवर्तित करें? या आप एक प्रकार का निर्देश बनाना चाहते हैं जो केवल लोअरकेस कुंजी (उन्हें डालने पर) की अनुमति देता है? – Jordi

+0

जैसा कि आप उदाहरण में देख सकते हैं, कुछ चाबियाँ लोअरकेस नहीं हैं। मैं यह सुनिश्चित करना चाहता हूं कि प्रत्येक JSON कुंजी लोअरकेस हो। – Natim

उत्तर

21
>>> d = {"your": "DATA", "FROM": "above"} 
>>> dict((k.lower(), v) for k, v in d.iteritems()) 
{'from': 'above', 'your': 'DATA'} 
>>> def lower_keys(x): 
... if isinstance(x, list): 
...  return [lower_keys(v) for v in x] 
... elif isinstance(x, dict): 
...  return dict((k.lower(), lower_keys(v)) for k, v in x.iteritems()) 
... else: 
...  return x 
... 
>>> lower_keys({"NESTED": {"ANSWER": 42}}) 
{'nested': {'answer': 42}} 
+0

मैंने केवल उठाया है कि आप नेस्टेड डिक्ट्स और सूचियों को विशेष रूप से अपने आत्म-उत्तर से इलाज करना चाहते हैं; आम तौर पर मैं इसे एक अलग स्तर पर संभालता हूं। –

+3

पायथन 3 पर आप समझ का उपयोग कर सकते हैं और 'dict (...)' -> 'd = {k.lower(): v के लिए v, v में d.items()}' – Delblanco

2

यहाँ मेरी समाधान है:

def lower_key(in_dict): 
    if type(in_dict) is dict: 
     out_dict = {} 
     for key, item in in_dict.items(): 
      out_dict[key.lower()] = lower_key(item) 
     return out_dict 
    elif type(in_dict) is list: 
     return [lower_key(obj) for obj in in_dict] 
    else: 
     return in_dict 
+0

अच्छा रिकर्सिव समाधान। – ThomasH

4

जब से तुम स्पष्ट रूप से उल्लेख नहीं किया है कि आप क्या करना चाहते हैं: सभी कुंजियों को लोअरकेस में

कनवर्ट करते हैं:

>>> y = dict((k.lower(), v) for k, v in x.iteritems()) 

चेक के लिए कुंजी:

>>> for k in x.iterkeys(): 
    if k.islower(): 
     print k, 'True' 
    else: 
     print k, 'False' 
+0

की आवश्यकता नहीं होगी .iteritems() और .iterkeys() के साथ समस्या यह है कि वे रिकर्सिव नहीं हैं। – ThomasH

8

यहाँ एक समाधान है कि एक लोअरकेस कुंजी स्थापित करने की मनाही है:

class LowerCaseDict(dict): 
    def __setitem__(self, key, val): 
     if not key.islower(): 
      raise TypeError, "%s key must be lowercase" % key 
     dict.__setitem__(self, key, val) 

ld = LowerCaseDict() 
ld['g']='g' 
+6

या, बस '__setitem__' करें' dict .__ setitem __ (self, key.lower(), val) '। सामान्य रूप से इस दृष्टिकोण के साथ समस्या यह है कि कन्स्ट्रक्टर और '.update' __setitem__ का उपयोग नहीं करते हैं - आपको इसके आसपास काम करने की आवश्यकता होगी, या' लोअरकेसडिक्ट ({'Foo': 1, 'bar': 2}) ' अपेक्षित कार्य नहीं करेगा (इसे मेरे रास्ते के लिए कम नहीं करेगा या आपके रास्ते के लिए टाइपरर नहीं बढ़ाएगा)। –

+0

आपको यह भी सुनिश्चित करना होगा कि प्रत्येक नेस्टेड dict के लिए लोअरकेसडिक्ट का उपयोग करना भी सुनिश्चित करें। – ThomasH

+0

@ क्रिस महान टिप्पणी। – ThomasH

2

तुम सिर्फ जांच अगर वे सभी लोअरकेस (आपका शब्दों चाहते हैं, का उपयोग करते हुए "सुनिश्चित", स्पष्ट नहीं है लेकिन मुझे लगता है यह नहीं है कि आप क्या चाहते), तो आप ऐसा कर सकते हैं दृढ़तापूर्वक एक पंक्ति में:

all(k.islower() for k in x.iterkeys()) 
2

यहाँ एक पूर्ण समाधान

from requests import CaseInsensitiveDict 
है

या यदि आप कोड देखना चाहते हैं:

class CaseInsensitiveDict(dict): 

    """Basic case insensitive dict with strings only keys.""" 

    proxy = {} 

    def __init__(self, data): 
     self.proxy = dict((k.lower(), k) for k in data) 
     for k in data: 
      self[k] = data[k] 

    def __contains__(self, k): 
     return k.lower() in self.proxy 

    def __delitem__(self, k): 
     key = self.proxy[k.lower()] 
     super(CaseInsensitiveDict, self).__delitem__(key) 
     del self.proxy[k.lower()] 

    def __getitem__(self, k): 
     key = self.proxy[k.lower()] 
     return super(CaseInsensitiveDict, self).__getitem__(key) 

    def get(self, k, default=None): 
     return self[k] if k in self else default 

    def __setitem__(self, k, v): 
     super(CaseInsensitiveDict, self).__setitem__(k, v) 
     self.proxy[k.lower()] = k 
संबंधित मुद्दे