तानाशाह [कुंजी] के बजाय तानाशाही (कुंजी) क्यों?


649

आज, मैं उस dictपद्धति पर आया हूं, getजिसने शब्दकोश में एक कुंजी दी है, जो संबंधित मान लौटाता है।

यह कार्य किस उद्देश्य के लिए उपयोगी है? अगर मैं एक शब्दकोश में एक महत्वपूर्ण के साथ जुड़े एक मूल्य खोजने के लिए करना चाहता था, मैं सिर्फ क्या कर सकते हैं dict[key], और यह एक ही बात रिटर्न:

dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")

1
dictionary["foo"]और dictionary.get("foo")यद्यपि अलग व्यवहार करते हैं।
निकल्स बी।

33
dictionary.get("Age") के रूप में ही लिख रहा है dictionary["Age"] or None तो यह स्पष्ट रूप से KeyError अपवाद को हैंडल करता है
yosemite_k

5
@yosemite_k मुझे यहां कुछ संदर्भ याद आ रहे हैं, लेकिन dictionary['non-existent key'] or Noneअभी भी KeyErrorमेरे लिए (v3.6 तक) उठाना चाहिए । क्या आप समझा सकते हैं कि आपका क्या मतलब है?
nivk

@nivk शब्दकोश ['गैर-मौजूद कुंजी'] त्रुटि उठाता है, और उस त्रुटि को स्पष्ट रूप से नियंत्रित किया जाना चाहिए। यदि इसके बजाय आप शब्दकोश () का उपयोग करते हैं (जो कि शाब्दिक रूप से शब्दकोश ['गैर-मौजूद कुंजी'] या कोई भी नहीं) जिसका अपवाद निहित रूप से नियंत्रित किया जाता है।
yosemite_k

जवाबों:


990

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

dictionary.get("bogus", default_value)

रिटर्न default_value(जो भी आप इसे चुनते हैं), जबकि

dictionary["bogus"]

एक उठाना होगा KeyError

यदि छोड़ा गया default_valueहै None, ऐसा है

dictionary.get("bogus")  # <-- No default specified -- defaults to None

Noneजैसे लौटता है

dictionary.get("bogus", None)

चाहेंगे।


1
क्या यह वैसा ही होगा dictionary.get("bogus") or my_default? मैंने देखा है कि लोग कुछ मामलों में इसका इस्तेमाल करते हैं और मैं सोच रहा था कि क्या एक के बजाय एक का उपयोग करने का कोई फायदा है (पठनीयता के अलावा)
एल्गोरिथम

15
@MustafaS: अगर "bogus"में एक महत्वपूर्ण है dictionaryऔर dictionary.get("bogus")रिटर्न एक मूल्य जो एक बूलियन संदर्भ में गलत का आकलन (यानी एक Falsey मूल्य), जैसे 0 या कोई रिक्त स्ट्रिंग, ''है, तो dictionary.get("bogus") or my_defaultकरने के लिए मूल्यांकन करेगा my_defaultजबकि dictionary.get("bogus", my_default)Falsey मूल्य लौट आते हैं। तो नहीं, के dictionary.get("bogus") or my_defaultबराबर नहीं है dictionary.get("bogus", my_default)। किसका उपयोग करना है यह आपके इच्छित व्यवहार पर निर्भर करता है।
अप्रयुक्त डेस

3
@MustafaS: उदाहरण के लिए, मान लीजिए x = {'a':0}। फिर x.get('a', 'foo')लौटता है 0लेकिन x.get('a') or 'foo'लौटता है 'foo'
अप्रयुक्त

3
उपयोग करते समय एक संभावित चेतावनी dictionary.get('key'): यदि शब्दकोश में मान हैं तो यह भ्रामक हो सकता है None। रिटर्न वैल्यू (दूसरा वैकल्पिक तर्क) निर्दिष्ट किए बिना यह सत्यापित करने का कोई तरीका नहीं है कि क्या कुंजी मौजूद नहीं थी या यदि उसका मान है None। इस विशिष्ट मामले में मैं उपयोग करने पर विचार करूंगा try-except-KeyError
आरती गोजेन्स

1
यह ध्यान देने योग्य है कि डिफ़ॉल्ट मान को निर्दिष्ट करने के लिए अभिव्यक्ति "गेट" कॉल में मूल्यांकन की जाती है, और इसलिए प्रत्येक एक्सेस पर मूल्यांकन किया जाता है। एक क्लासिक विकल्प (या तो कीर्रर हैंडलर या एक डेडिकेटेट का उपयोग करके) केवल डिफ़ॉल्ट मान का मूल्यांकन करना है, यदि कुंजी गायब है। यह एक बंद / लैम्ब्डा को एक बार बनाने और किसी भी लापता कुंजी का मूल्यांकन करने की अनुमति देता है।
टॉम स्टैम्बॉज

142

dict.get()विधि क्या है ?

जैसा कि पहले ही उल्लेख किया गया है कि getविधि में एक अतिरिक्त पैरामीटर है जो लापता मूल्य को इंगित करता है। प्रलेखन से

get(key[, default])

कुंजी के लिए मान लौटाएं यदि कुंजी शब्दकोश में है, तो डिफ़ॉल्ट रूप से। यदि डिफ़ॉल्ट नहीं दिया गया है, तो यह किसी को भी नहीं चूकता है, ताकि यह विधि कभी भी न उठे KeyError

एक उदाहरण हो सकता है

>>> d = {1:2,2:3}
>>> d[1]
2
>>> d.get(1)
2
>>> d.get(3)
>>> repr(d.get(3))
'None'
>>> d.get(3,1)
1

कहीं गति में सुधार हैं?

जैसा कि यहां बताया गया है ,

ऐसा लगता है कि सभी तीन दृष्टिकोण अब समान प्रदर्शन (एक दूसरे के लगभग 10% के भीतर), शब्दों की सूची के गुणों से अधिक या कम स्वतंत्र हैं।

पहले getकाफी धीमा था, हालांकि अब डिफ़ॉल्ट मूल्य को वापस करने के अतिरिक्त लाभ के साथ-साथ गति लगभग तुलनीय है। लेकिन हमारी सभी जिज्ञासाओं को दूर करने के लिए, हम एक बड़ी सूची पर परीक्षण कर सकते हैं (ध्यान दें कि परीक्षण में केवल सभी मान्य कुंजियाँ देखना शामिल है)

def getway(d):
    for i in range(100):
        s = d.get(i)

def lookup(d):
    for i in range(100):
        s = d[i]

अब इन दो कार्यों का उपयोग करते हुए समय timeit

>>> import timeit
>>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
20.2124660015
>>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))
16.16223979

जैसा कि हम देख सकते हैं कि लुकअप फंक्शन की तुलना में तेज है क्योंकि इसमें फंक्शन लुकिंग नहीं है। इसके माध्यम से देखा जा सकता हैdis

>>> def lookup(d,val):
...     return d[val]
... 
>>> def getway(d,val):
...     return d.get(val)
... 
>>> dis.dis(getway)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_ATTR                0 (get)
              6 LOAD_FAST                1 (val)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        
>>> dis.dis(lookup)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (val)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE  

यह कहां उपयोगी होगा?

जब भी आप डिक्शनरी देख रहे हों, तो जब भी आप डिफॉल्ट वैल्यू देना चाहते हैं, तो यह उपयोगी होगा। यह कम करता है

 if key in dic:
      val = dic[key]
 else:
      val = def_val

एक लाइन में, val = dic.get(key,def_val)

यह कहाँ उपयोगी नहीं होगा?

जब भी आप यह बताना चाहते हैं KeyErrorकि विशेष कुंजी उपलब्ध नहीं है। एक डिफ़ॉल्ट मान लौटाने से यह जोखिम भी होता है कि एक विशेष डिफ़ॉल्ट मान एक कुंजी भी हो सकता है!

क्या getफीचर में ऐसा होना संभव है dict['key']?

हाँ! हमें __missing__एक तानाशाह उपवर्ग में लागू करने की जरूरत है ।

एक नमूना कार्यक्रम हो सकता है

class MyDict(dict):
    def __missing__(self, key):
        return None

एक छोटा प्रदर्शन हो सकता है

>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'

32
StackOverflow जवाब के स्वर्ण मानक!
अपोलो डेटा


1
एक और अच्छी परीक्षा if k in dict and dict[k]:बनाम होगी if dict.get(k):। यह उस स्थिति को कवर करता है जब हमें जांचने की आवश्यकता होती है कि क्या कुंजी मौजूद है, और यदि 'हाँ' - क्या मूल्य ?, कुछ इस तरह से dict = {1: '', 2: 'some value'}:।
टाइटनफाइटर

7
कृपया याद रखें कि डिफॉल्ट वैल्यू का मूल्यांकन डिक्शनरी में होने के बावजूद किया जाता है, इसलिए इसके बजाय dictionary.get(value, long_function())कोई उपयोग करने पर विचार कर सकता हैdictionary.get(value) or long_function()
Kresimir

अह @Kresimir, सच। मुझे उस प्रश्न में से एक साक्षात्कार में मिला था जिसका मैंने सामना किया था (मुझे इसके बारे में पता नहीं था जब मैंने मूल रूप से यह उत्तर पोस्ट किया था)। मुझे इसके बारे में याद दिलाने के लिए धन्यवाद।
भार्गव राव

32

getएक दूसरा वैकल्पिक मूल्य लेता है। यदि आपके शब्दकोश में निर्दिष्ट कुंजी मौजूद नहीं है, तो यह मान वापस कर दिया जाएगा।

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

यदि आप दूसरा पैरामीटर नहीं देते हैं, Noneतो वापस कर दिया जाएगा।

यदि आप अनुक्रमणिका का उपयोग करते हैं dictionary['Year'], तो कोई भी कुंजी नहीं बढ़ेगी KeyError


19

मैं अजगर का उपयोग करते हुए वेब डेटा को स्क्रैप करने में एक व्यावहारिक उदाहरण दूंगा, बहुत बार आपको बिना मूल्यों के साथ चाबियाँ मिलेंगी, उन मामलों में आप त्रुटियों का उपयोग करेंगे यदि आप शब्दकोश ['कुंजी'] का उपयोग करते हैं, जबकि Dictionary.get ('कुंजी' ',' return_otherwise ') को कोई समस्या नहीं है।

इसी तरह, मैं '' .join (सूची) का उपयोग सूची के विरोध के रूप में करूँगा [0] यदि आप किसी सूची से एकल मान कैप्चर करने का प्रयास करते हैं।

आशा है ये मदद करेगा।

[संपादित करें] यहाँ एक व्यावहारिक उदाहरण है:

कहते हैं, आप एक एपीआई कॉल कर रहे हैं, जो एक JOSN फ़ाइल देता है जिसे आपको पार्स करने की आवश्यकता है। पहला JSON निम्न जैसा दिखता है:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

दूसरा JOSN इस तरह है:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

ध्यान दें कि दूसरा JSON "submitdate_ts" कुंजी याद कर रहा है, जो किसी भी डेटा संरचना में बहुत सामान्य है।

इसलिए जब आप उस कुंजी के मान को एक लूप में एक्सेस करने का प्रयास करते हैं, तो क्या आप इसे निम्नलिखित के साथ कॉल कर सकते हैं:

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

आप कर सकते हैं, लेकिन यह आपको दूसरी JSON लाइन के लिए एक ट्रेसबैक त्रुटि देगा, क्योंकि कुंजी बस मौजूद नहीं है।

इसे कोड करने का उपयुक्त तरीका निम्नलिखित हो सकता है:

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

{'x': दूसरा स्तर कोई त्रुटि होने से बचने के लिए नहीं है। यदि आप स्क्रैपिंग कर रहे हैं तो बेशक आप कोड में अधिक दोष सहिष्णुता का निर्माण कर सकते हैं। जैसे अगर कोई शर्त है तो पहले बताएं


2
एक अच्छा जवाब, किसी भी अन्य के सामने पोस्ट किया गया है, जो अधिक बढ़ा हुआ होता है, और शायद स्वीकार किया जाता है, अगर आपने कुछ कोड उदाहरण (मेरे से +1, हालांकि) पोस्ट किए थे
Mawg का कहना है कि मोनिका

2
@ मेवग I ने हाल ही में अपने शोध के लिए एक स्क्रैपिंग प्रोजेक्ट किया था। यह मूल रूप से एक एपीआई कॉल कर रहा था और JSON फ़ाइलों को पार्स कर रहा था। मैंने अपना आरए किया था। प्रमुख मुद्दों में से एक वह सीधे कुंजी को बुला रहा था, जब कई चाबियाँ वास्तव में गायब हैं। मैं ऊपर दिए गए पाठ में एक उदाहरण पोस्ट करूंगा।
केविन

इस के बहुआयामी पहलू से निपटने के लिए धन्यवाद! लगता है कि आप भी {} x के बजाय {} कर सकते हैं: कोई नहीं}
bluppfisk

17

उद्देश्य यह है कि यदि कुंजी नहीं मिली है, तो आप एक डिफ़ॉल्ट मान दे सकते हैं, जो बहुत उपयोगी है

dictionary.get("Name",'harry')

8

यह कार्य किस उद्देश्य के लिए उपयोगी है?

एक विशेष उपयोग एक शब्दकोश के साथ गिना जा रहा है। मान लेते हैं कि आप दिए गए सूची में प्रत्येक तत्व की घटनाओं की संख्या को गिनना चाहते हैं। ऐसा करने का सामान्य तरीका एक शब्दकोश बनाना है जहां चाबियाँ तत्व हैं और मूल्य घटना की संख्या है।

fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
    if fruit not in d:
        d[fruit] = 0
    d[fruit] += 1

.get()विधि का उपयोग करके , आप इस कोड को अधिक कॉम्पैक्ट और स्पष्ट बना सकते हैं:

for fruit in fruits:
    d[fruit] = d.get(fruit, 0) + 1

7

उपयोग करते समय जागरूक होने के लिए एक गेटा .get() :

यदि शब्दकोश में कॉल में प्रयुक्त कुंजी है .get()और इसका मान है None, तो .get()विधि वापस आ जाएगीNone तो डिफ़ॉल्ट मान की आपूर्ति होने भी ।

उदाहरण के लिए, निम्नलिखित रिटर्न None, 'alt_value'उम्मीद के मुताबिक नहीं :

d = {'key': None}
d.get('key', 'alt_value')

.get()दूसरा मूल्य तभी लौटाया जाता है, जब आपूर्ति की गई कुंजी डिक्शनरी में न हो, न कि उस कॉल का रिटर्न वैल्यू None


1
यह मुझे मिल गया: \ इसे हल करने का एक तरीका यह है कि d.get('key') or 'alt_value'यदि आप जानते हैं कि यह हो सकता हैNone
डैनियल होम्स

4

तानाशाह [कुंजी] के बजाय तानाशाही (कुंजी) क्यों?

0. सारांश

की तुलना में dict[key],dict.get कुंजी की तलाश में एक कमबैक मूल्य प्रदान करता है।

1. परिभाषा

get (कुंजी [, डिफ़ॉल्ट]) 4. अंतर्निहित प्रकार - पायथन 3.6.4rc1 प्रलेखन

कुंजी के लिए मान लौटाएं यदि कुंजी शब्दकोश में है, तो डिफ़ॉल्ट रूप से। यदि डिफॉल्ट नहीं दिया गया है, तो यह किसी को भी डिफॉल्ट नहीं करता है, ताकि यह तरीका कभी भी कीरर न उठे।

d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'

2. समस्या यह हल करती है।

यदि बिना default value, तो आपको इस तरह के अपवाद को संभालने के लिए बोझिल कोड लिखना होगा।

def get_harry_info(key):
    try:
        return "{}".format(d[key])
    except KeyError:
        return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'

एक सुविधाजनक समाधान के रूप में, dict.getअवांछित कोड के ऊपर से बचने के लिए एक वैकल्पिक डिफ़ॉल्ट मूल्य का परिचय देता है ।

3. निष्कर्ष

dict.get यदि शब्दकोष से अनुपस्थित है, तो अपवाद से निपटने के लिए एक अतिरिक्त डिफ़ॉल्ट मान विकल्प है


0

एक अंतर यह है कि यह एक फायदा हो सकता है, यदि हम एक ऐसी कुंजी की तलाश में हैं जो मौजूद नहीं है तो हमें कोई भी नहीं मिलेगा, जैसे कि जब हम कोष्ठक संकेतन का उपयोग करते हैं, तो उस स्थिति में जब हमें कोई त्रुटि मिलती है:

print(dictionary.get("address")) # None
print(dictionary["address"]) # throws KeyError: 'address'

अंतिम विधि जो प्राप्त करने के तरीके के बारे में अच्छी है, वह यह है कि यह एक डिफ़ॉल्ट मान के लिए एक अतिरिक्त वैकल्पिक तर्क प्राप्त करता है, अगर हमने किसी छात्र के स्कोर मान को प्राप्त करने की कोशिश की है, लेकिन छात्र के पास कोई स्कोर कुंजी नहीं है जिसे हम प्राप्त कर सकते हैं इसके बजाय एक 0।

इसलिए ऐसा करने के बजाय (या कुछ इसी तरह):

score = None
try:
    score = dictionary["score"]
except KeyError:
    score = 0

हम यह कर सकते हैं:

score = dictionary.get("score", 0)
# score = 0

-1

उपयोग के आधार पर इस getविधि का उपयोग करना चाहिए ।

उदाहरण 1

In [14]: user_dict = {'type': False}

In [15]: user_dict.get('type', '')

Out[15]: False

In [16]: user_dict.get('type') or ''

Out[16]: ''

example2

In [17]: user_dict = {'type': "lead"}

In [18]: user_dict.get('type') or ''

Out[18]: 'lead'

In [19]: user_dict.get('type', '')

Out[19]: 'lead'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.