2013-05-10 10 views
8

मुझे अजगर के साथ JSON को पार्स करते समय समस्याएं आ रही हैं, और अब मैं फंस गया हूं।
समस्या यह है कि मेरे JSON की इकाइयां हमेशा समान नहीं होती हैं। JSON है कुछ की तरह:पायथन के साथ JSON पार्सिंग: खाली फ़ील्ड

"entries":[ 
{ 
"summary": "here is the sunnary", 
"extensions": { 
    "coordinates":"coords", 
    "address":"address", 
    "name":"name" 
    "telephone":"123123" 
    "url":"www.blablablah" 
}, 
} 
] 

मैं, JSON के माध्यम से स्थानांतरित कर सकते हैं उदाहरण के लिए:

for entrie in entries: 
    name =entrie['extensions']['name'] 
    tel=entrie['extensions']['telephone'] 

समस्या आता है क्योंकि कभी कभी, JSON सभी "फील्ड" नहीं है, उदाहरण के लिए, telephone फ़ील्ड, कभी-कभी गायब है, इसलिए, स्क्रिप्ट KeyError के साथ विफल हो जाती है, क्योंकि इस प्रविष्टि में कुंजी टेलीफोन गुम है।
तो, मेरा प्रश्न: मैं इस स्क्रिप्ट को कैसे चला सकता हूं, एक रिक्त स्थान छोड़कर टेलीफोन गुम है? मैं के साथ की कोशिश की है:

if entrie['extensions']['telephone']: 
    tel=entrie['extensions']['telephone'] 

लेकिन मुझे लगता है ठीक नहीं है। बजाय एक KeyError जुटाने की जब कुंजी नहीं मिला है

entries['extensions'].get('telephone') 

get दूसरा तर्क (डिफ़ॉल्ट, None) वापस आ जाएगी:

उत्तर

11

उपयोग dict.get बजाय []:

entries['extensions'].get('telephone', '') 

या, बस ।

0

कई उपयोगी शब्दकोश विशेषताएं हैं जिनका उपयोग आप इस के साथ काम करने के लिए कर सकते हैं।

सबसे पहले, आप परीक्षण करने के लिए किया जाए या नहीं एक महत्वपूर्ण एक शब्दकोश में मौजूद है in उपयोग कर सकते हैं:

if 'telephone' in entrie['extensions']: 
    tel=entrie['extensions']['telephone'] 

get भी उपयोगी हो सकती; यह अगर कुंजी याद आ रही है आप एक डिफ़ॉल्ट मान निर्दिष्ट करने के लिए अनुमति देता है:

tel=entrie['extensions'].get('telephone', '') 

सिवाय इसके, आप मानक पुस्तकालय के collections.defaultdict पर गौर कर सकता है, लेकिन यह है कि overkill हो सकता है।

8

डेटा केवल एक ही स्थान पर याद आ रही है, तो dict.get भरें लापता मान अनुपलब्ध के लिए इस्तेमाल किया जा सकता है:

tel = d['entries'][0]['extensions'].get('telelphone', '') 

यदि समस्या और अधिक व्यापक है, तो आप JSON पार्सर उपयोग एक हो सकता है defaultdict या नियमित शब्दकोश के बजाय कस्टम शब्दकोश। उदाहरण के लिए, दिए गए JSON स्ट्रिंग:

json_txt = '''{ 
    "entries": [ 
     { 
      "extensions": { 
       "telephone": "123123", 
       "url": "www.blablablah", 
       "name": "name", 
       "coordinates": "coords", 
       "address": "address" 
      }, 
      "summary": "here is the summary" 
     } 
    ] 
}''' 

साथ पार्स यह:

>>> class BlankDict(dict): 
     def __missing__(self, key): 
      return '' 

>>> d = json.loads(json_txt, object_hook=BlankDict) 

>>> d['entries'][0]['summary'] 
u'here is the summary' 

>>> d['entries'][0]['extensions']['color'] 
'' 

एक तरफ ध्यान दें के रूप में, आप को साफ-अप अपने डेटासेट और स्थिरता को लागू करना चाहते हैं, वहाँ एक अच्छा कहा जाता है उपकरण है Kwalify जो JSON (और YAML पर) पर स्कीमा सत्यापन करता है;

+1

अच्छा, मैं इस बेहतर तो 'defaultdict चाहते 'क्योंकि '__missing__' विधि के अंदर एक संभावित बग पकड़ने के लिए कुछ तर्क जोड़ने में सक्षम होगा। 'डिफॉल्टडिक्ट' के साथ मैं हमेशा क्रिंग करता हूं क्योंकि जब मैं टाइपो बनाता हूं तो मुझे एक KeyError नहीं मिलेगा। –

0

दो तरीके।

एक यह सुनिश्चित करना है कि आपके शब्दकोश मानक हैं, और जब आप उन्हें पढ़ते हैं तो उनके पास सभी फ़ील्ड होते हैं। दूसरी बातों को एक्सेस करते समय सावधान रहना है।

यहाँ बनाने का एक उदाहरण है सुनिश्चित करें कि आपके शब्दकोशों मानक हैं:

__reference_extensions = { 
    # fill in with all standard keys 
    # use some default value to go with each key 
    "coordinates" : '', 
    "address" : '', 
    "name" : '', 
    "telephone" : '', 
    "url" : '' 
} 

entrie = json.loads(input_string) 
d = entrie["extensions"] 
for key, value in __reference_extensions: 
    if key not in d: 
     d[key] = value 

यहाँ सावधान किया जा रहा है जब शब्दकोशों तक पहुँचने का एक उदाहरण है:

for entrie in entries: 
    name = entrie['extensions'].get('name', '') 
    tel = entrie['extensions'].get('telephone', '') 
संबंधित मुद्दे