क्या Python 2.7 का उपयोग करके KeyError से बचने के लिए JSON कोड को पुनरावर्ती defaultdict में लोड करने का कोई तरीका है?

उदाहरण के लिए:

from __future__ import print_function
from collections import defaultdict
import json

S =  '{"a": [{"b": "TEST1", "p": "TEST2"}, {"b": "TEST3", "p": "TEST4"}]}'

d = json.loads(S)
nd = lambda: defaultdict(nd)
ni = nd()
print('1: ', ni['a'][0]['b'])
ni.update(d)
print('2: ', ni['a'][0]['b'])
print('3: ', ni['a'][1]['p'])
print('4: ', ni['a'][1]['c'])

नतीजा

1:  defaultdict(<function <lambda> at 0x0266F530>, {})
2:  TEST1
3:  TEST4
Traceback (most recent call last):
  File "C:/...", line 16, in <module>
    print('4: ', ni['a'][1]['c'])
KeyError: 'c'

ऐसा लगता है कि ni.update(d) ni dict के रूप में काम करता है, और पुनरावर्ती defaultdict की तरह नहीं। क्या dict को पुनरावर्ती defaultdict में जोड़ने और इसके गुणों को बनाए रखने का कोई तरीका है?

मैं निम्नलिखित के समान चरण 4 पर परिणाम की अपेक्षा करता हूं:

4:  defaultdict(<function <lambda> at 0x0266F530>, {})
1
Vladimir Popov 7 जून 2018, 01:06

1 उत्तर

सबसे बढ़िया उत्तर

एक पुनरावर्ती निर्देश बनाने के लिए पर्याप्त नहीं है। आपको JSON ऑब्जेक्ट को अपने ताना में पुनरावर्ती रूप से लोड करना होगा।

आपके कोड में क्या होता है कि ni['a'] एक सामान्य निर्देश है, न कि एक प्रकार का nd। जब आप ni.update(d) चलाते हैं, तो अपडेट d को पार करने के लिए पर्याप्त चतुर नहीं है, प्रत्येक स्तर पर वस्तुओं को समान प्रकार की वस्तुओं में लिखना। इसके बजाय, यह केवल d के प्रथम-स्तरीय मानों और कुंजियों को ni में कॉपी करता है। प्रथम-स्तर के मूल्य केवल सामान्य निर्देश या जो कुछ भी हैं।

ni को सही ढंग से प्रारंभ करने के लिए, आपको एक पुनरावर्ती फ़ंक्शन लिखना होगा जो यह निर्धारित करता है कि प्रत्येक मान एक तानाशाही, सरणी या अदिश है। यदि यह एक निर्देश है, तो इसे nd पर कॉल करना होगा, और फिर परिणाम को उन मानों से भरना होगा जिनके लिए यह उसी पुनरावर्ती तरीके से कार्य करेगा।

या, आप तर्क object_hook से json.loads का उपयोग कर सकते हैं। देखें https://docs.python.org/2/library/json विवरण के लिए .html#json.load। आप यहां जो भी फ़ंक्शन पास करते हैं, उसे पार्सिंग के किसी भी स्तर पर बनाए गए प्रत्येक निर्देश पर बुलाया जाएगा। तो समारोह

def defaultdict_from_dict(d):
    nd = lambda: defaultdict(nd)
    ni = nd()
    ni.update(d)
    return ni

या कुछ ऐसा ही शायद आपके लिए चाल चलेगा।

4
jwg 7 जून 2018, 01:36