পাইথনের ফাঁকে ফাঁকে আমার কি 'has_key ()' বা 'in' ব্যবহার করা উচিত?


910

আমি অবাক হই যে আরও ভাল করার জন্য:

d = {'a': 1, 'b': 2}
'a' in d
True

বা:

d = {'a': 1, 'b': 2}
d.has_key('a')
True

উত্তর:


1286

in স্পষ্টতই বেশি অজগর।

আসলে has_key()পাইথন 3.x এ সরানো হয়েছিল


3
অতিরিক্ত হিসাবে, পাইথন 3, কি পরিবর্তে মান অস্তিত্ব জন্য চেক করতে, d.values মধ্যে >>> 1 () চেষ্টা
riza

217
যদিও একটি আধা-গোটাছা তা এড়াতে হবে তা নিশ্চিত করা: আপনি "কিছু_ডিক্ট.কিজ () -তে কী" না করে "কিছু_ডিক্টে কী"। উভয়ই শব্দার্থগতভাবে সমান, তবে কর্মক্ষমতা অনুসারে পরবর্তীটি অনেক ধীর (ও (এন) বনাম ও (1)) হয়। আমি লোকেদের "ডিক্ট.কিজ ()" করতে দেখে ভেবেছি এটি আরও স্পষ্ট এবং তাই আরও ভাল।
অ্যাডাম পার্কিন

2
@AdamParkin আমি আমার উত্তর আপনার মন্তব্য প্রদর্শিত stackoverflow.com/a/41390975/117471
ব্রুনো Bronosky

8
পাইথন ৩-এ অ্যাডাম পারকিন, keys()একটি অনুলিপিের চেয়ে অভিধানে কেবল একটি সেট-মত দৃষ্টিভঙ্গি, সুতরাং x in d.keys()ও (1)। তবুও, x in dআরও পাইথোনিক।
আর্থার টাক্কা

2
@ অ্যাডাম পারকিন আকর্ষণীয়, আমি এটি দেখিনি। আমি মনে করি এটির কারণ x in d.keys()অবশ্যই একটি অস্থায়ী অবজেক্ট তৈরি এবং ধ্বংস করতে হবে, যা মেমরি বরাদ্দকরণের সাথে সম্পূর্ণ হয়, যেখানে x in d.keys()কেবল একটি পাটিগণিত অপারেশন (হ্যাশ গণনা করা) এবং একটি অনুসন্ধান করা হচ্ছে। দ্রষ্টব্য যে d.keys()এটি কেবল 10 গুণ বেশি দীর্ঘ, যা এখনও সত্যিই দীর্ঘ নয়। আমি চেক করিনি তবে আমি এখনও নিশ্চিত যে এটি কেবল ও (1)।
আর্থার টাক্কা

253

in হ্যান্ডস ডাউন জিতেছে, কেবল কমনীয়তায় নয় (এবং অবমূল্যায়ন করা হচ্ছে না ;-) নয় বরং পারফরম্যান্সেও উদাহরণস্বরূপ:

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop

নীচের পর্যবেক্ষণটি সর্বদা সত্য নয় তবে আপনি লক্ষ্য করবেন যে সাধারণত পাইথনে দ্রুত দ্রবণটি আরও মার্জিত এবং পাইথোনিক হয়; এ কারণেই -mtimeitএটি সহায়ক - এটি কেবল এখানে এবং সেখানে একশো ন্যানোসেকেন্ডগুলি সঞ্চয় করার পক্ষে নয় ! -)


4
এটির জন্য ধন্যবাদ, "কিছু_ডিক্টে" আসলে ও (1) অনেক সহজ (যা 1999 বলে 999 বাড়াতে চেষ্টা করুন এবং আপনি রানটাইমটি প্রায় একই রকমের পাবেন) যাচাই করে দেখিয়েছেন।
অ্যাডাম পার্কিন

2
has_keyও (1) এও প্রদর্শিত হবে।
ড্যান-জিএফ


42

ব্যবহারের dict.has_key()করেন (এবং কেবল যদি) আপনার কোড 2.3 আগের (যখন পাইথন সংস্করণ দ্বারা runnable হতে প্রয়োজন বোধ করা হয় key in dictচালু করা হয়)।


1
2013 সালে ওয়েবস্পিয়ার আপডেটটি জাইথন ​​2.1 কে এর মূল স্ক্রিপ্টিং ভাষা হিসাবে ব্যবহার করে। সুতরাং দুর্ভাগ্যক্রমে এটি এখনও দরকারী জিনিস হিসাবে লক্ষ্য করা গেছে, আপনি এটি নোট করেছেন পাঁচ বছর পরে।
আর্টঅফ ওয়ারফেয়ার

23

একটি উদাহরণ রয়েছে যেখানে inপ্রকৃতপক্ষে আপনার অভিনয়কে হত্যা করে।

আপনি যদি inও (1) পাত্রে ব্যবহার করেন যা কেবল প্রয়োগ করে __getitem__এবং has_key()তবে __contains__আপনি ও (1) অনুসন্ধানকে ও (এন) অনুসন্ধানে পরিণত করবেন (যেমন inলিনিয়ার অনুসন্ধানে ফিরে আসে )__getitem__ )।

সংশোধন স্পষ্টতই তুচ্ছ:

def __contains__(self, x):
    return self.has_key(x)

6
এই উত্তরটি পোস্ট হওয়ার সময় প্রযোজ্য ছিল, তবে 99.95% পাঠক এটি নিরাপদে উপেক্ষা করতে পারবেন। ইন অধিকাংশ ক্ষেত্রেই, আপনি যদি কিছু কাজ করছি এই অস্পষ্ট আপনি এটা জানেন করব।
wizzwizz4

2
এটি সত্যিই কোনও সমস্যা নয়। পাইথন 2 অভিধানেরhas_key() জন্য নির্দিষ্টin/ __contains__ব্যবহার করার সঠিক API; ঐ পাত্রে যেখানে একটি সম্পূর্ণ স্ক্যান এড়ানো সম্ভব নয় কোন জন্য has_key()পদ্ধতি যাহাই হউক না কেন , এবং যদি সেখানে একটি হে (1) পদ্ধতির তারপর যে ব্যবহার-কেস নির্দিষ্ট সমস্যা জন্য সঠিক ডাটা টাইপ নিতে হবে এবং তাই আপ বিকাশকারীকে দেওয়া হবে।
মার্টিজন পিটারস

15

has_keyঅভিধানের পদ্ধতি, তবে inযে কোনও সংগ্রহে কাজ করবে এবং __contains__অনুপস্থিত থাকা inসত্ত্বেও সংগ্রহটি পুনরুক্তি করার জন্য এটি অনুসন্ধানের জন্য অন্য কোনও পদ্ধতি ব্যবহার করবে।


1
এবং পুনরাবৃত্তকারীগুলিতে "x ইন এক্সরেঞ্জ (90, 200) <=> 90 <= x <200"
u0b34a0f6ae

1
…: এটি দেখতে খুব খারাপ ধারণা বলে মনে হচ্ছে: ২ এর পরিবর্তে 50 টি অপারেশন
ক্লিমেট

1
পাইথন 3-এ @ ক্লামেন্ট, বস্তুর inউপর পরীক্ষা করা আসলে এটি বেশ দক্ষ rangexrangeযদিও পাইথন 2 তে এর দক্ষতা সম্পর্কে আমি এতটা নিশ্চিত নই । ;)
সন্ধ্যা

@ পোশাকটি পাইথন 3 এ নেই; একটি মান সীমার মধ্যে রয়েছে কিনা __contains__তা তুচ্ছভাবে গণনা করতে পারে ।
মার্টিজন পিটারস

1
@ অ্যালেক্সানড্রেহুট আপনার সময় অনুসারে rangeপ্রতিবার একটি নতুন ইভেন্ট তৈরির ওভারহেড অন্তর্ভুক্ত । একক, প্রাক-বিদ্যমান উদাহরণটি ব্যবহার করে আমার সময়কালে "পূর্ণসংখ্যার পরিসীমা" পরীক্ষা প্রায় 40% দ্রুত হয়।
মিস্টারমিয়াগি

14

ডিক.হাস_কি () এর সমাধান অবমাননাকৃত, 'ইন' ব্যবহার করুন - উত্তম পাঠ্য সম্পাদক 3

এখানে আমি 'বয়সের' নামে অভিধানের একটি উদাহরণ নিয়েছি -

ages = {}

# Add a couple of names to the dictionary
ages['Sue'] = 23

ages['Peter'] = 19

ages['Andrew'] = 78

ages['Karren'] = 45

# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:

    print "Sue is in the dictionary. She is", ages['Sue'], "years old"

else:

    print "Sue is not in the dictionary"

6
সঠিক, তবে এটি ইতিমধ্যে উত্তর দেওয়া হয়েছিল, স্ট্যাকোভ্লোতে স্বাগতম, উদাহরণস্বরূপ ধন্যবাদ, সর্বদা উত্তরগুলি পরীক্ষা করুন যদিও!
igorgue

@igorgue আমি তার কাছে নিচে বাসকারীদের সম্পর্কে নিশ্চিত নই। তার উত্তর ইতিমধ্যে জবাব দেওয়া অনুরূপ হতে পারে, কিন্তু তিনি একটি উদাহরণ প্রদান করে। এসও এর উত্তর হওয়ার মতো উপযুক্ত কি না?
অক্ষত আগরওয়াল

14

অ্যাডাম পার্টিনের মন্তব্যে অ্যালেক্স মার্তেলির পারফরম্যান্স পরীক্ষাগুলি প্রসারিত করা হচ্ছে ...

$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
    x = t.timeit(number)
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
    d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(  99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop

ওয়ান্ডারফুল পরিসংখ্যান, কখনও কখনও স্পষ্ট অন্তর্নিহিত (অন্তত দক্ষতা) চেয়ে ভাল হতে পারে ...
বরুণ

আপনাকে ধন্যবাদ, @ ভারুন। আমি এই উত্তর সম্পর্কে ভুলে গিয়েছিলাম। আমাকে আরও প্রায়ই এই জাতীয় পরীক্ষা করাতে হবে। আমি নিয়মিত দীর্ঘ থ্রেডগুলি পড়ে থাকি যেখানে লোকেরা সেরা উপায় about সম্পর্কে জিনিসগুলির বিষয়ে তর্ক করে । তবে আমি খুব কমই মনে করতে পারি যে প্রমাণ পাওয়া এটি কতটা সহজ ছিল ।
ব্রুনো ব্রোনোস্কি

0

আপনার যদি এরকম কিছু থাকে:

t.has_key(ew)

পাইথন ৩. এক্স এবং তারপরে চালানোর জন্য এটি নীচে পরিবর্তন করুন:

key = ew
if key not in t

6
না, আপনি পরীক্ষাটি উল্টে দিয়েছেন। t.has_key(ew)ফেরৎ Trueযদি মান ewরেফারেন্স এছাড়াও অভিধানে একটি চাবিকাঠি। key not in tফেরৎ Trueযদি মান না অভিধানে। তদুপরি, key = ewউপনামটি খুব, খুব নিরর্থক। সঠিক বানানটি হ'ল if ew in t। 8 বছর আগে থেকে গৃহীত উত্তর যা ইতিমধ্যে আপনাকে জানিয়েছে।
মার্টিজান পিটারস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.