कैसे जांचा जाए कि कोई चर पाइथन में डिक्शनरी है?


214

अगर अजगर एक डिक्शनरी है तो आप कैसे चेक करेंगे?

उदाहरण के लिए, मैं इसे शब्दकोश में मूल्यों के माध्यम से पाश करना चाहूंगा जब तक कि यह एक शब्दकोश नहीं मिलता। फिर, जो इसे पाता है, उसके माध्यम से लूप करें:

dict = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
for k, v in dict.iteritems():
    if ###check if v is a dictionary:
        for k, v in v.iteritems():
            print(k, ' ', v)
    else:
        print(k, ' ', v)

इसके अलावा stackoverflow.com/questions/378927/… (जो ऊपर के एक डुप्लिकेट के रूप में चिह्नित है)।
NPE


40
नहीं, यह एक ही सवाल नहीं है। इस प्रश्न का उत्तर और यहाँ सूचीबद्ध अन्य प्रश्नों में सभी में समान रूप से समान जानकारी है। लेकिन "यह कैसे जांचा जाए कि एक वेरिएबल अजगर में डिक्शनरी है" का उत्तर है "यूज़ टाइप () या आइंस्टीन ())" जो तब एक नए प्रश्न की ओर ले जाता है, जो कि टाइप () और आइंस्टीन () के बीच का अंतर क्या है । लेकिन पहला प्रश्न पूछने वाला व्यक्ति संभवतः यह नहीं जान सकता कि पहले प्रश्न का उत्तर कब तक है। एर्गो, अलग-अलग प्रश्न, जो तब मायने रखता है जब आप साइट पर अपने प्रश्न की तलाश कर रहे हों।

13
मैं @mbakeranalecta से सहमत हूँ मैं यहाँ सवाल के जवाब की तलाश में आया था "कैसे जाँचें कि एक चर एक पायथन में एक शब्दकोश है?" और मैंने कभी भी अपने उत्तर को "आइंस्टीनेंस के बीच अंतर () और प्रकार () अजगर में" के रूप में देखने के लिए नहीं सोचा होगा।
लोदेबारी

5
यह जाँचने के लिए कि एक चर विशेष रूप से एक शब्दकोश है, तो आपको संभवतः उपयोग करना चाहिए isinstance(v, collections.abc.Mapping)। दूसरे शब्दों में, यह "आइंस्टीनेंस के बीच अंतर () और प्रकार () के बारे में एक सटीक डुप्लिकेट नहीं है।"
जोश केली

जवाबों:


279

यदि आप उप-वर्गित थे, तो आप उपयोग if type(ele) is dictया उपयोग कर सकते हैं :isinstance(ele, dict)dict

d = {'abc':'abc','def':{'ghi':'ghi','jkl':'jkl'}}
for ele in d.values():
    if isinstance(ele,dict):
       for k, v in ele.items():
           print(k,' ',v)

70
मैं इस सवाल का जवाब नीचे मतदान क्योंकि साधारण प्रश्न का सही जवाब है: isinstance(ele, collections.Mapping)। यह के लिए काम करता है dict(), collections.OrderedDict()और collections.UserDict()। सवाल में उदाहरण पादरीक के काम करने के जवाब के लिए पर्याप्त विशिष्ट है, लेकिन यह सामान्य मामले के लिए पर्याप्त नहीं है।
अलेक्जेंडर रियाज़ोव

3
मैंने इस उत्तर को अस्वीकार कर दिया क्योंकि यदि आप आह्वान करने जा ele.items()रहे हैं तो आप प्रकार की जाँच क्यों कर रहे हैं? EAFP / बतख टाइपिंग यहाँ काम करता है, सिर्फ लपेट for k,v in ele.items()में try...except (AttributeError, TypeError)। यदि अपवाद उठाया गया है, तो आप जानते हैं कि eleइसमें कोई itemsपैदावार नहीं होती है ...
काउबर्ड

@ पैडरिक कनिंघम आपके काल्पनिक किनारे के मामले के लिए आवश्यक होगा कि आपके "100% एक तानाशाह नहीं" कस्टम वर्ग 1 में एक items()विधि थी। 2. जो सिर्फ एक पुनरावृत्त करने के लिए हुआ था और 3. जहाँ उस पुनरावृत्ति के प्रत्येक तत्व को 2 के रूप में दर्शाया जा सकता है। -tuple। इस बिंदु पर आपकी कस्टम ऑब्जेक्ट पहले से ही आधे से पहले ही लागू हो चुकी है। सूचीबद्ध कोड के प्रयोजनों के लिए हमने केवल नेस्टेड तत्व के सशर्त विस्तार के बारे में परवाह की है, और आपकी कस्टम वस्तु पहले से ही लागू होती है। (यह थोड़ी विडंबना है कि आप आलोचना करते हैं
@ अलेक्जेंडर रियाज़ोव

1
@PadraicCunningham मैं लोगों को नहीं सिखाना चाहूंगा, जो शुरुआत से ही पायथन के विरोधी-पैटर्न से परिचित नहीं हैं। पाइथन में बहुत कम उपयोग के मामले हैं, जिनमें स्पष्ट टाइपकास्टिंग की आवश्यकता होती है - एक खराब कार्यान्वयन को शुरू करने से सबसे अधिक स्टेम ('देव वस्तु, मानक पुस्तकालय / भाषा निर्माण, आदि की अनदेखी) से शुरू होता है। मूल प्रश्न अपने आप में एक XY समस्या है। ओपी को प्रकार की जांच करने की आवश्यकता क्यों है? क्योंकि उनके कोड के अनुसार वे वास्तव में क्या करना चाहते हैं, यह जांचना है कि क्या उनके संग्रह में कोई आइटम संग्रह की तरह व्यवहार करता है (लागू होते हैं items()जो एक नेस्टेड पुनरावृत्ति पैदा करता है)।
काऊबर्ट जूल

4
@AlexanderRyzhov उत्तर के रूप में उस दृष्टिकोण को पोस्ट क्यों नहीं किया? BTW के रूप में जोश केली ने सुझाव देते हुए ऊपर टिप्पणी की हैcollections.abc.Mapping , एक नोट उपयुक्त हो सकता है कि वे समान हों, लेकिन collections.abcपायथन 3.3 से पहले उपलब्ध नहीं हैं। collections.Mappingउपनाम अभी भी पाइथन 3.6 में उपलब्ध है, लेकिन प्रलेखित नहीं है, इसलिए शायद एक को पसंद करना चाहिए collections.abc.Maping
युसिन वाशियो

5

यदि आप एक चर पायथन में एक शब्दकोश है, तो आप कैसे जांचेंगे?

यह एक उत्कृष्ट प्रश्न है, लेकिन यह दुर्भाग्यपूर्ण है कि सबसे अधिक उत्तर दिया गया उत्तर एक खराब सिफारिश के साथ होता है, type(obj) is dict

(ध्यान दें कि आपको भी उपयोग नहीं करना चाहिए dict एक चर नाम के रूप में - यह बिलिन ऑब्जेक्ट का नाम है।)

यदि आप ऐसा कोड लिख रहे हैं जो आयात किया जाएगा और दूसरों द्वारा उपयोग किया जाता है, तो यह न मानें कि वे सीधे ताना-बाना का उपयोग करेंगे - यह मानते हुए कि अनुमान आपके कोड को अधिक अनम्य बनाता है और इस मामले में, आसानी से छिपे हुए बग बनाएं जो प्रोग्राम को त्रुटि नहीं देगा। ।

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

isवस्तु पहचान के लिए एक परीक्षा है । यह विरासत का समर्थन नहीं करता है, यह किसी भी अमूर्तता का समर्थन नहीं करता है, और यह इंटरफ़ेस का समर्थन नहीं करता है।

इसलिए मैं कई विकल्प प्रदान करूँगा जो करते हैं।

सहायक विरासत:

यह पहली सिफारिश मैं होगा है, क्योंकि यह उपयोगकर्ताओं को एक dict के अपने स्वयं के उपवर्ग, या आपूर्ति करने के लिए अनुमति देता है OrderedDict, defaultdictया Counterसे संग्रह मॉड्यूल:

if isinstance(any_object, dict):

लेकिन और भी अधिक लचीले विकल्प हैं।

सहायक सार:

from collections.abc import Mapping

if isinstance(any_object, Mapping):

यह आपके कोड के उपयोगकर्ता को अमूर्त मानचित्रण के अपने स्वयं के कस्टम कार्यान्वयन का उपयोग करने की अनुमति देता है, जिसमें कोई उपवर्ग भी शामिल है dict, और फिर भी सही व्यवहार मिलता है।

इंटरफ़ेस का उपयोग करें

आप आमतौर पर OOP की सलाह सुनते हैं, "एक इंटरफ़ेस के लिए प्रोग्राम"।

यह रणनीति पायथन के बहुरूपता या बतख-टाइपिंग का लाभ उठाती है।

तो बस विशिष्ट उम्मीद त्रुटियों को पकड़ने इंटरफ़ेस का उपयोग करने का प्रयास, ( AttributeErrorमामले में कोई है .itemsऔर TypeErrorमामले में itemsप्रतिदेय नहीं है) एक उचित वापस आने के साथ - और अब किसी भी वर्ग है कि लागू करता है कि इंटरफेस आप अपने आइटम (टिप्पणी दे देंगे .iteritems()पायथन में चला गया है 3):

try:
    items = any_object.items()
except (AttributeError, TypeError):
    non_items_behavior(any_object)
else: # no exception raised
    for item in items: ...

शायद आप सोच सकते हैं कि इस तरह के डक-टाइपिंग का उपयोग बहुत अधिक झूठी सकारात्मक के लिए अनुमति देने में बहुत दूर जाता है, और यह इस कोड के लिए आपके उद्देश्यों के आधार पर हो सकता है।

निष्कर्ष

isमानक नियंत्रण प्रवाह के प्रकार जाँचने के लिए उपयोग न करें । उपयोग करें isinstance, जैसे अमूर्तता पर विचार करें , Mappingया MutableMappingसीधे इंटरफ़ेस का उपयोग करके, पूरी तरह से जाँच से बचने पर विचार करें।


3

ओपी ने शुरुआती चर को बाहर नहीं किया है, इसलिए पूर्णता के लिए यहां एक कथित शब्दकोश को संसाधित करने के सामान्य मामले को कैसे संभालना है जिसमें शब्दकोशों के रूप में आइटम शामिल हो सकते हैं।

इसके अलावा शुद्ध पायथन (3.8) ने उपरोक्त टिप्पणियों में शब्दकोश के लिए परीक्षण करने का तरीका सुझाया

from collections.abc import Mapping

dict = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}

def parse_dict(in_dict): 
    if isinstance(in_dict, Mapping):
        for k, v in in_dict.items():
            if isinstance(v, Mapping):
                for k, v in v.items():
                    print(k, v)
            else:
                print(k, v)

parse_dict(dict)

dict.iteritems()पायथन 3 में मौजूद नहीं है, आपको dict.items()इसके बजाय उपयोग करना चाहिए ।
अर्केलिस

@ अर्केलिस उफ़, बस उस हिस्से को कॉपी / पेस्ट किया गया, उसे इंगित करने के लिए धन्यवाद - अब ठीक किया गया।
कोडमैंटल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.