কারণ তালিকাগুলি পরিবর্তনীয়, dict
কীগুলি (এবং set
সদস্যদের) হ্যাশযোগ্য হওয়া দরকার, এবং পরিবর্তনীয় বস্তুগুলি হ্যাশ করা একটি খারাপ ধারণা কারণ হ্যাশ মানগুলি উদাহরণ বৈশিষ্ট্যের ভিত্তিতে গণনা করা উচিত ।
এই উত্তরে আমি কয়েকটি দৃ concrete় উদাহরণ দেব, আশা করি বিদ্যমান উত্তরগুলির উপরে মান যুক্ত করুন। প্রতিটি অন্তর্দৃষ্টি set
ডেটাস্ট্রাক্টরের উপাদানগুলিতেও প্রযোজ্য ।
উদাহরণ 1 : একটি পরিবর্তনীয় বস্তুর হ্যাশিং যেখানে হ্যাশ মানটি বস্তুর পরিবর্তিত বৈশিষ্ট্যের উপর ভিত্তি করে।
>>> class stupidlist(list):
... def __hash__(self):
... return len(self)
...
>>> stupid = stupidlist([1, 2, 3])
>>> d = {stupid: 0}
>>> stupid.append(4)
>>> stupid
[1, 2, 3, 4]
>>> d
{[1, 2, 3, 4]: 0}
>>> stupid in d
False
>>> stupid in d.keys()
False
>>> stupid in list(d.keys())
True
পরিবর্তনের পরে stupid
, হ্যাশ পরিবর্তিত হওয়ার কারণে এটি আর ডিকের সাথে আর খুঁজে পাওয়া যাবে না। ডিকের কীগুলি তালিকার তালিকায় কেবল একটি রৈখিক স্ক্যান stupid
।
উদাহরণ 2 : ... তবে কেন কেবল একটি ধ্রুবক হ্যাশ মান হয় না?
>>> class stupidlist2(list):
... def __hash__(self):
... return id(self)
...
>>> stupidA = stupidlist2([1, 2, 3])
>>> stupidB = stupidlist2([1, 2, 3])
>>>
>>> stupidA == stupidB
True
>>> stupidA in {stupidB: 0}
False
এটা একটা ভাল ধারণা হিসাবে ভাল কারণ সমান বস্তু অভিন্নরুপে যেমন যে আপনি তাদের একটি জানতে পারেন হ্যাশ উচিত নয় dict
বা set
।
উদাহরণ 3 : ... ঠিক আছে, সমস্ত দৃষ্টান্ত জুড়ে ধ্রুব হ্যাশগুলির কী ?!
>>> class stupidlist3(list):
... def __hash__(self):
... return 1
...
>>> stupidC = stupidlist3([1, 2, 3])
>>> stupidD = stupidlist3([1, 2, 3])
>>> stupidE = stupidlist3([1, 2, 3, 4])
>>>
>>> stupidC in {stupidD: 0}
True
>>> stupidC in {stupidE: 0}
False
>>> d = {stupidC: 0}
>>> stupidC.append(5)
>>> stupidC in d
True
প্রত্যাশা মতো জিনিসগুলি কাজ করছে বলে মনে হয় তবে কী হচ্ছে তা নিয়ে চিন্তা করুন: যখন আপনার শ্রেণীর সমস্ত দৃষ্টান্ত একই হ্যাশ মান তৈরি করে, যখনই একটি dict
বা উপস্থিতিতে কী হিসাবে দুটিরও বেশি উদাহরণ থাকবে তখন আপনার একটি হ্যাশ সংঘর্ষ হবে set
।
my_dict[key]
বা key in my_dict
(বা item in my_set
) এর সাথে সঠিক উদাহরণ stupidlist3
সন্ধানের জন্য ডিকের কীগুলিতে (সবচেয়ে খারাপ ক্ষেত্রে) উদাহরণ রয়েছে তত বেশি সমতা পরীক্ষা করতে হবে । এই মুহুর্তে, অভিধানের উদ্দেশ্য - ও (1) চেহারা - সম্পূর্ণ পরাজিত। এটি নিম্নলিখিত সময়গুলিতে প্রদর্শিত হয় (আইপিথন দিয়ে সম্পন্ন)।
উদাহরণ 3 জন্য কিছু সময়
>>> lists_list = [[i] for i in range(1000)]
>>> stupidlists_set = {stupidlist3([i]) for i in range(1000)}
>>> tuples_set = {(i,) for i in range(1000)}
>>> l = [999]
>>> s = stupidlist3([999])
>>> t = (999,)
>>>
>>> %timeit l in lists_list
25.5 µs ± 442 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit s in stupidlists_set
38.5 µs ± 61.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit t in tuples_set
77.6 ns ± 1.5 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
আপনি দেখতে পাচ্ছেন, আমাদের সদস্যপদ পরীক্ষাটি stupidlists_set
সামগ্রিকভাবে রৈখিক স্ক্যানের চেয়েও ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে lists_list
হ্যাশ সংঘর্ষের সংঘর্ষ ছাড়াই আপনার একটি সেটে প্রত্যাশিত সুপার ফাস্ট লিকুইচিং টাইম (ফ্যাক্টর 500) থাকে।
টিএল; ডিআর: আপনি কী tuple(yourlist)
হিসাবে ব্যবহার করতে পারেন dict
, কারণ টিপলগুলি স্থাবর ও হ্যাশেবল।