शब्दकोश कुंजी उपलब्ध नहीं है, तो कोई भी वापस लौटें


488

मुझे एक शब्दकोश मान प्राप्त करने के लिए एक तरीका चाहिए अगर इसकी कुंजी मौजूद है, या बस वापस आती है None, अगर यह नहीं होता है।

हालाँकि, KeyErrorयदि आप उस कुंजी की खोज करते हैं जो मौजूद नहीं है , तो पायथन अपवाद छोड़ देता है। मुझे पता है कि मैं कुंजी की जांच कर सकता हूं, लेकिन मैं कुछ और स्पष्ट देख रहा हूं। Noneयदि कुंजी मौजूद नहीं है, तो क्या केवल लौटने का एक तरीका है?


74
बस के .get(key)बजाय का उपयोग करें[key]
Gabe

12
एक तानाशाह KeyError अपवाद उठाता है। यह "वापसी key_error" नहीं है।
बेर

3
कुंजी तक पहुंचना और अपवाद को पकड़ना पाइथन में पूरी तरह से ठीक है। यह एक अच्छी तरह से ज्ञात और अक्सर उपयोग किया जाने वाला डिज़ाइन पैटर्न है। यदि आप इसके बजाय कोई नहीं लौटाते हैं, तो मूल्य के रूप में किसी को भी संग्रहीत करना असंभव हो जाता है, जो कुछ मामलों में प्रासंगिक हो सकता है।
बेर

1
कभी-कभी आप शब्दकोश में "कोई नहीं" प्रविष्टियों को और अनुपलब्ध प्रविष्टियों को एक ही मान लेना चाहते हैं, उस स्थिति में स्वीकृत उत्तर काम को ठीक करने के लिए लगता है।
cib

@ मैंने स्पष्ट करने के लिए प्रश्न संपादित किया है। आप भी ऐसा कर सकते थे।
törzsmókus

जवाबों:


812

आप उपयोग कर सकते हैं dict.get()

value = d.get(key)

जो वापस आ जाएगी None, तो key is not in d। आप एक अलग डिफ़ॉल्ट मान भी प्रदान कर सकते हैं जो इसके बदले लौटाया जाएगा None:

value = d.get(key, "empty")

47
ध्यान दें कि डिफ़ॉल्ट में कमबैक वाला दूसरा संस्करण अभी भी वापस आ जाएगा Noneयदि कुंजी को स्पष्ट रूप से मैप किया गया Noneहो। यदि वह नहीं है जो आप चाहते हैं, तो आप कुछ का उपयोग कर सकते हैं d.get(key) or "empty"
17

15
@cib: अच्छी बात है, लेकिन समाधान एक ऐसी ही समस्या है - अगर कुंजी किसी भी "falsy" मान पर मैप किया जाता है (जैसे [], "", False, 0.0या वास्तव में None), तो अपने समाधान हमेशा वापसी होगी 0। यदि आप Noneमूल्यों के रूप में उम्मीद करते हैं, तो आपको if key in d:चेक को स्पष्ट रूप से करना होगा ।
टिम पिएत्जेकर

1
@cib उसके लिए खुश है, मैं यहाँ क्या गलत कर रहा था बाहर काम नहीं कर सकता।
wobbily_col

@TimPietzcker - क्या आप कृपया अपना उत्तर बता सकते हैं? d.get (कुंजी) या "खाली" कुंजी के मामले में किसी भी 'मिथ्या' मूल्यों के लिए मैप किए जाने पर "खाली" है अगर मैं गलत नहीं हूं।
मिलोमिंदरबिंदर 15

@MiloMinderbinder: "empty"यदि keyएक वैध कुंजी नहीं है तो लौटा दिया जाता है d। इसका मूल्य से कोई लेना-देना नहीं keyहै।
टिम पीटरज़ैफ़

63

और अधिक आश्चर्य ना करें। यह भाषा में बनाया गया है।

    >>> मदद (तानाशाही)

    मॉड्यूल के निर्माण में वर्ग के हुक्म पर मदद:

    वर्ग तानाशाही (वस्तु)
     | तानाशाही () -> नया खाली शब्दकोश
     | तानाशाही (मानचित्रण) -> नया शब्द मैपिंग ऑब्जेक्ट से आरंभ किया गया
     | (कुंजी, मूल्य) जोड़े
    ...
     |  
     | प्राप्त(...)
     | डगेट (k [, d]) -> D [k] अगर k में D, बाकी d। घ कोई नहीं करने के लिए चूक।
     |  
    ...

22

उपयोग dict.get

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


19

आपको कक्षा get()से विधि का उपयोग करना चाहिएdict

d = {}
r = d.get('missing_key', None)

इसका परिणाम यह होगा r == None। यदि शब्दकोश में कुंजी नहीं मिली है, तो फ़ंक्शन दूसरा तर्क लौटाता है।


19
आपको Noneस्पष्ट रूप से पास होने की आवश्यकता नहीं है । यह डिफ़ॉल्ट है।
ब्योर्न पोलेक्स

18

यदि आप अधिक पारदर्शी समाधान चाहते हैं, तो आप dictइस व्यवहार को प्राप्त करने के लिए उपवर्ग कर सकते हैं:

class NoneDict(dict):
    def __getitem__(self, key):
        return dict.get(self, key)

>>> foo = NoneDict([(1,"asdf"), (2,"qwerty")])
>>> foo[1]
'asdf'
>>> foo[2]
'qwerty'
>>> foo[3] is None
True

2
@marineau: जैसा कि मैंने एक टिप्पणी में एक अन्य उत्तर का उल्लेख किया है, के साथ समस्या defaultdictयह है कि यह हर बार एक तत्व बढ़ेगा जो अभी तक अनुरोध में नहीं है। यह हमेशा वांछनीय नहीं है।
ब्योर्न पोलेक्स

@ BjörnPollex यह अब तक सुरुचिपूर्ण एक है, किसी भी गहराई का समर्थन करने के लिए इसे कैसे बढ़ाया जाए, इस पर कोई सुराग? मैं करने का यह अर्थ foo['bar']['test']['sss']वापस जाने के लिए Noneअपवाद के बजाय एक गहराई के बाद यह देना शुरू TypeErrorके बजायKeyError
nehem

@itsneo। आप की पूरी संरचना का निर्माण कर सकते हैं NoneDicts। यदि KeyErrorअंतरतम वस्तु में यह होता है तो इससे मदद मिलेगी । अन्यथा समस्या यह है, कि एक बार जब आप एक Noneवस्तु वापस करते हैं तो आप उसे अब सदस्यता नहीं दे सकते। एक बदसूरत हैक किसी अन्य ऑब्जेक्ट को वापस करना होगा जो कि परीक्षण करता है None। हालांकि सावधान रहें कि इससे भयानक कीड़े हो सकते हैं।
मग्गू_

@ BjörnPollex क्या इसे बदलना ठीक return dict.get(self, key)है return super().get(key)? उदाहरण के लिए, अगर मैं आदेश के बजाय ऑर्डरडेड का उपयोग करने का निर्णय लेता हूं, उदाहरण के लिए, मुझे कोड की कई पंक्तियों को बदलने के बारे में चिंता करने की आवश्यकता नहीं है।
वुड

@ हाँ, यह वास्तव में बहुत अच्छा होगा!
ब्योर्न पोलेक्स

12

मैं आमतौर पर इस तरह की स्थितियों के लिए एक डिफ़ॉल्ट का उपयोग करता हूं । आप एक फ़ैक्टरी विधि की आपूर्ति करते हैं जो कोई तर्क नहीं लेता है और एक नई कुंजी को देखते समय एक मूल्य बनाता है। यह तब अधिक उपयोगी होता है जब आप नई चाबियों पर एक खाली सूची की तरह कुछ वापस करना चाहते हैं ( उदाहरण देखें )।

from collections import defaultdict
d = defaultdict(lambda: None)
print d['new_key']  # prints 'None'

19
इसके साथ समस्या defaultdictयह है कि यह हर बार एक गैर-मौजूदा तत्व का अनुरोध करने के लिए बढ़ता रहेगा।
ब्योर्न पोलेक्स

8

आप किसी dictऑब्जेक्ट की get()विधि का उपयोग कर सकते हैं , जैसा कि अन्य पहले ही सुझा चुके हैं। वैकल्पिक रूप से, वास्तव में आप क्या कर रहे हैं, इसके आधार पर, आप try/exceptइस तरह से एक सूट का उपयोग कर सकते हैं :

try:
   <to do something with d[key]>
except KeyError:
   <deal with it not being there>

जिसे मामले को संभालने के लिए एक बहुत ही "पायथोनिक" दृष्टिकोण माना जाता है।


7

एक लाइन समाधान होगा:

item['key'] if 'key' in item else None

शब्दकोश मूल्यों को नई सूची में जोड़ने का प्रयास करते समय यह उपयोगी है और एक डिफ़ॉल्ट प्रदान करना चाहते हैं:

जैसे।

row = [item['key'] if 'key' in item else 'default_value']

5

जैसा कि दूसरों ने ऊपर कहा है, आप प्राप्त () का उपयोग कर सकते हैं।

लेकिन एक कुंजी की जांच करने के लिए, आप यह भी कर सकते हैं:

d = {}
if 'keyname' in d:

    # d['keyname'] exists
    pass

else:

    # d['keyname'] does not exist
    pass

मैं अब देखता हूं कि आप पहले से ही जानते हैं कि यह कैसे करना है। मैं अपनी पोस्ट हटाने जा रहा था, लेकिन मैं इसे दूसरों के लिए संदर्भ के लिए छोड़ दूंगा।
मारेक पी

4
इस दृष्टिकोण को आमतौर पर दो बार देखने के लिए कुंजी की आवश्यकता होती है जब यह वहां होता है, जो संभवतः getविधि का कारण है ।
मार्टिउ

0

मुझे python2 बनाम python3 में जो संभव था, उससे निकाल दिया गया। मैं इसका जवाब इस बात पर दूंगा कि मैंने अजगर के लिए क्या किया। मेरा उद्देश्य सरल था: जाँच करें कि क्या शब्दकोश प्रारूप में एक जोंस प्रतिक्रिया ने त्रुटि दी या नहीं। मेरे शब्दकोश को "टोकन" कहा जाता है और मेरी कुंजी जिसे मैं ढूंढ रहा हूं वह "त्रुटि" है। मैं कुंजी "त्रुटि" की तलाश कर रहा हूं और अगर यह वहां किसी के मूल्य पर स्थापित नहीं कर रहा था, तो जाँच है कि मूल्य कोई भी है, यदि मेरे कोड के साथ आगे बढ़ें। यदि मेरे पास कुंजी "त्रुटि" है, तो एक और बयान संभाल लेगा।

if ((token.get('error', None)) is None):
    do something

-2

यदि आप इसे कर सकते हैं False, तो, वहाँ भी है हेट्र्ट बिल्ट-इन funtion:

e=dict()
hasattr(e, 'message'):
>>> False
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.