ডিক [কী] এর পরিবর্তে ডিক্টেট (কী) কেন?


648

আজ, আমি সেই 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

@ নিভক অভিধান ['অস্তিত্বহীন কী'] ত্রুটি উত্থাপন করে এবং সেই ত্রুটিটি স্পষ্টভাবে পরিচালনা করা উচিত। পরিবর্তে যদি আপনি অভিধান ব্যবহার করেন get
yosemite_k

উত্তর:


989

কীটি অনুপস্থিত থাকলে এটি আপনাকে ডিফল্ট মান সরবরাহ করতে দেয়:

dictionary.get("bogus", default_value)

প্রত্যাবর্তন default_value(আপনি যা যা চয়ন করুন), যদিও

dictionary["bogus"]

বাড়াতে হবে a 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
@ মুস্তফাএস: যদি "bogus"কোনও কী থাকে dictionaryএবং dictionary.get("bogus")একটি মান প্রদান করে যা বুলিয়ান প্রসঙ্গে (যেমন একটি ফালসি মান), যেমন 0 বা একটি খালি স্ট্রিংয়ে ফ্যালসের মূল্যায়ন করে '', তবে dictionary.get("bogus") or my_defaultমূল্যায়ন করবে my_defaultযেখানে dictionary.get("bogus", my_default)ফলসী মানটি ফিরিয়ে দেবে। সুতরাং না, dictionary.get("bogus") or my_defaultসমতুল্য নয় dictionary.get("bogus", my_default)। কোনটি ব্যবহার করবেন তা আপনার ইচ্ছা আচরণের উপর নির্ভর করে।
unutbu

3
@ মুস্তফাএস: উদাহরণস্বরূপ, ধরুন x = {'a':0}। তারপরে x.get('a', 'foo')ফিরে আসে 0কিন্তু x.get('a') or 'foo'ফিরে আসে 'foo'
unutbu

3
ব্যবহার করার সময় একটি সম্ভাব্য সাবধানতা dictionary.get('key'): অভিধানের মান থাকলে এটি বিভ্রান্তিকর হতে পারে None। রিটার্ন মান (দ্বিতীয় alচ্ছিক যুক্তি) উল্লেখ না করে কীটি উপস্থিত ছিল না বা এর মানটি রয়েছে কিনা তা যাচাই করার কোনও উপায় নেই None। এই নির্দিষ্ট ক্ষেত্রে আমি ব্যবহার বিবেচনা করব try-except-KeyError
আর্ট গুসেন্সেন্স

1
এটি লক্ষণীয় যে ডিফল্ট মান নির্দিষ্ট করার জন্য অভিব্যক্তিটি "get" কলটিতে মূল্যায়ন করা হয় এবং তাই প্রতিটি অ্যাক্সেসের জন্য মূল্যায়ন করা হয়। একটি ক্লাসিক বিকল্প (কোনও কীআররর হ্যান্ডলার বা প্রিডিকেট ব্যবহার করে) কেবল কীটি অনুপস্থিত থাকলেই ডিফল্ট মানটি মূল্যায়ন করতে হয়। এটি কোনও ক্লোজার / ল্যাম্বদা একবার তৈরি করতে এবং যে কোনও অনুপস্থিত কীতে মূল্যায়ন করার অনুমতি দেয়।
টম স্ট্যামবগ

142

dict.get()পদ্ধতিটি কী ?

ইতিমধ্যে উল্লিখিত হিসাবে getপদ্ধতিটিতে একটি অতিরিক্ত পরামিতি রয়েছে যা অনুপস্থিত মানকে নির্দেশ করে। ডকুমেন্টেশন থেকে

get(key[, default])

অভিধানে যদি কী থাকে তবে কীটির মানটি ফিরিয়ে দিন else যদি ডিফল্টটি দেওয়া না হয় তবে এটি ডিফল্ট নয় কারও সাথে, যাতে এই পদ্ধতিটি কখনই উত্থাপন করে না 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
স্ট্যাকওভারফ্লো উত্তরগুলির সোনার মান!
অ্যাপোলো ডেটা


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()
কোনওটি

আহ @ ক্রেসিমির, সত্য। আমি যে সাক্ষাত্কারটির মুখোমুখি হয়েছিলাম তার একটিতে আমি এই প্রশ্নটি পেয়েছি (আমি মূলত এই উত্তরটি পোস্ট করার সময় আমি এটি সম্পর্কে জানতাম না)। এটি সম্পর্কে আমাকে মনে করিয়ে দেওয়ার জন্য ধন্যবাদ।
ভার্গব রাও

32

getদ্বিতীয় optionচ্ছিক মান নেয়। যদি নির্দিষ্ট কী আপনার অভিধানে উপস্থিত না থাকে তবে এই মানটি ফিরে আসবে।

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

আপনি যদি দ্বিতীয় প্যারামিটার Noneনা দেন তবে ফিরে আসবে।

আপনি যদি সূচি হিসাবে ব্যবহার করেন তবে dictionary['Year']অস্তিত্বহীন কীগুলি উত্থাপন করবে KeyError


19

অজগর ব্যবহার করে ওয়েব ডেটা স্ক্র্যাপ করার জন্য আমি একটি ব্যবহারিক উদাহরণ দেব, অনেক সময় আপনি কোনও মান না দিয়ে কীগুলি পেয়ে যাবেন, সেই ক্ষেত্রে আপনি অভিধান ['কী'] ব্যবহার করলে আপনি ত্রুটি পেয়ে যাবেন, যেখানে অভিধান.get ('কী) ',' वापसी_ অন্যদিকে ') এর কোনও সমস্যা নেই।

একইভাবে, আমি যদি তালিকা থেকে একটি একক মান ক্যাপচার করার চেষ্টা করি তবে আমি ['জিন (তালিকা) তালিকার বিপরীতে [0] ব্যবহার করব।

আশা করি এটা সাহায্য করবে.

[সম্পাদনা] এখানে একটি বাস্তব উদাহরণ:

বলুন, আপনি এমন একটি এপিআই কল করছেন যা আপনাকে পার্স করার জন্য একটি জওএসএন ফাইল দেয়। প্রথম 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"}}

দ্বিতীয় জেএসএন এর মতো:

{"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"}}

মনে রাখবেন যে দ্বিতীয় জেএসওন "সাবমিট_টেটস" কীটি অনুপস্থিত, যা কোনও ডাটা স্ট্রাকচারে বেশ স্বাভাবিক।

সুতরাং যখন আপনি একটি লুপে key কীটির মানটি অ্যাক্সেস করার চেষ্টা করেন, আপনি কি নীচের সাথে এটি কল করতে পারেন:

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

আপনি পারতেন, তবে এটি আপনাকে দ্বিতীয় জেএসওএন লাইনের জন্য একটি ট্রেসব্যাক ত্রুটি দেবে, কারণ কীটি সহজভাবে বিদ্যমান নেই।

এটির কোডিং করার উপযুক্ত পদ্ধতিটি নিম্নলিখিত হতে পারে:

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

level 'x': দ্বিতীয় স্তরের ত্রুটি হওয়া এড়াতে কোনওটি নেই। আপনি যদি স্ক্র্যাপিং করে থাকেন তবে অবশ্যই কোডটিতে আপনি আরও বেশি ফল্ট সহনশীলতা তৈরি করতে পারেন। প্রথমে একটি শর্ত নির্দিষ্ট করে দেওয়া পছন্দ করুন


2
একটি ভাল উত্তর, অন্যদের আগে পোস্ট করা হয়েছে, যা আরও উত্সাহিত হত, এবং সম্ভবত আপনি গ্রহণ করেছেন, যদি আপনি কিছু কোড উদাহরণ পোস্ট করেন (তবে আমার কাছ থেকে +1)
মাওগ বলেছেন মোনিকা

2
@ মাওগ আমি সম্প্রতি আমার গবেষণার জন্য একটি স্ক্র্যাপিং প্রকল্প করেছি। এটি একটি এপিআই কল করে এবং মূলত JSON ফাইলগুলি পার্স করছে। আমার আরএ এটা করতে হয়েছিল। তাঁর কাছে থাকা মূল সমস্যাগুলির মধ্যে একটিটি সরাসরি কীটি কল করছিল, যখন অনেকগুলি কী আসলে অনুপস্থিত থাকে। আমি উপরের লেখায় একটি উদাহরণ পোস্ট করব।
কেভিন

এর বহুমাত্রিক দিকটি মোকাবেলার জন্য ধন্যবাদ! আপনার মতো শব্দ এমনকি {'x' এর পরিবর্তে just do করতে পারেন: কিছুই নেই}
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

একজন gotcha হয় যখন ব্যবহার সচেতন হতে হবে .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. সংজ্ঞা

(কী [, ডিফল্ট]) 4. অন্তর্নির্মিত প্রকারগুলি - পাইথন 3.6.4rc1 ডকুমেন্টেশন

অভিধানে যদি কী থাকে তবে কীটির মানটি ফিরিয়ে দিন else যদি ডিফল্টটি দেওয়া না হয় তবে এটি ডিফল্ট নয় কারও সাথে, যাতে এই পদ্ধতিটি কখনই কী-ইরার উত্থাপন করে না।

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অনিচ্ছুক কোডগুলি উপরে এড়ানো একটি alচ্ছিক ডিফল্ট মান প্রবর্তন করে।

৩. উপসংহার

dict.get অভিধান থেকে কীটি অনুপস্থিত থাকলে ব্যতিক্রম মোকাবেলায় অতিরিক্ত ডিফল্ট মান বিকল্প রয়েছে


0

একটি পার্থক্য, এটি একটি সুবিধা হতে পারে, তা হ'ল আমরা যদি এমন কীটি সন্ধান করি যা বিদ্যমান না থাকে তবে আমরা কিছুই পাব না, বন্ধনী স্বরলিপিটি ব্যবহার করার সময় নয়, এই ক্ষেত্রে আমরা ত্রুটি নিক্ষেপ করব:

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

শেষ পদ্ধতিটি get পদ্ধতির বিষয়ে দুর্দান্ত, এটি হ'ল এটি একটি ডিফল্ট মানের জন্য একটি অতিরিক্ত alচ্ছিক যুক্তি পায়, এটি হ'ল যদি আমরা কোনও শিক্ষার্থীর স্কোর মান পাওয়ার চেষ্টা করি তবে শিক্ষার্থীর কাছে স্কোর কী নেই যা আমরা পেতে পারি পরিবর্তে একটি 0

সুতরাং এটি করার পরিবর্তে (বা অনুরূপ কিছু):

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

আমরা এটা করতে পারি:

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

-1

ব্যবহারের ভিত্তিতে এই getপদ্ধতিটি ব্যবহার করা উচিত ।

Example1

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'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.