পাইথন এই লুপটি কখন (কখন) শেষ হবে সে সম্পর্কে কোনও প্রতিশ্রুতি দেয় না। পুনরাবৃত্তি চলাকালীন একটি সেট পরিবর্তন করা বাদ দেওয়া উপাদান, পুনরাবৃত্তি উপাদান এবং অন্যান্য অদ্ভুততার কারণ হতে পারে। কখনও এ জাতীয় আচরণের উপর নির্ভর করবেন না।
আমি যা বলতে চাইছি তা হ'ল বাস্তবায়ন বিশদ, বিজ্ঞপ্তি ছাড়াই পরিবর্তিত হতে পারে to যদি আপনি এমন কোনও প্রোগ্রাম লিখেন যা এর কোনওটির উপর নির্ভর করে, আপনার প্রোগ্রামটি পাইথন বাস্তবায়ন এবং সিপাইথন ৩.৮.২ ব্যতীত অন্য সংস্করণে কোনও মিল ফেলতে পারে।
কেন লুপটি 16 এ শেষ হয় তার সংক্ষিপ্ত ব্যাখ্যাটি হ'ল 16 হল প্রথম উপাদান যা পূর্ববর্তী উপাদানের তুলনায় নিম্ন হ্যাশ টেবিল সূচীতে স্থাপন করা হয়। সম্পূর্ণ ব্যাখ্যা নীচে।
পাইথন সেটের অভ্যন্তরীণ হ্যাশ টেবিলটিতে সর্বদা 2 আকারের শক্তি থাকে। আকার 2 ^ n এর টেবিলের জন্য, যদি কোনও সংঘর্ষ না ঘটে, উপাদানগুলি হ্যাশের টেবিলের অবস্থানগুলিতে তাদের হ্যাশের ন্যূনতম-তাত্পর্যপূর্ণ বিটগুলির সাথে সংগৃহীত থাকে। আপনি এটি প্রয়োগ করা দেখতে পারেন set_add_entry
:
mask = so->mask;
i = (size_t)hash & mask;
entry = &so->table[i];
if (entry->key == NULL)
goto found_unused;
বেশিরভাগ ছোট পাইথন ইনস হ্যাশ তাদের কাছে; বিশেষত, আপনার পরীক্ষার সমস্ত হিট তাদের কাছে। আপনি এটি প্রয়োগ করা দেখতে পারেন long_hash
। যেহেতু আপনার সেটটিতে দুটি হ্যাশগুলিতে সমান কম বিটযুক্ত দুটি উপাদান থাকে না তাই কোনও সংঘর্ষ হয় না।
পাইথন সেট পুনরায় সেটর সেটটির অভ্যন্তরীণ হ্যাশ টেবিলের মধ্যে একটি সাধারণ পূর্ণসংখ্যার সূচক সহ একটি সেটে তার অবস্থানের উপর নজর রাখে। পরবর্তী উপাদানটির জন্য অনুরোধ করা হলে, পুনরুক্তিকারী সূচকটি শুরু করে হ্যাশ টেবিলের মধ্যে একটি পপুলেটেড এন্ট্রি অনুসন্ধান করে, তারপরে সঞ্চিত সূচকটি সন্ধানের প্রবেশের পরপরই সেট করে এবং প্রবেশের উপাদানটি ফেরত দেয়। আপনি এটি দেখতে পারেন setiter_iternext
:
while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
i++;
si->si_pos = i+1;
if (i > mask)
goto fail;
si->len--;
key = entry[i].key;
Py_INCREF(key);
return key;
আপনার সেটটি শুরুতে 8 মাপের একটি হ্যাশ টেবিল এবং হ্যাশ টেবিলের 0
সূচক 0 তে কোনও ইনট অবজেক্টের পয়েন্টার দিয়ে শুরু হয় । পুনরুক্তিটি সূচক 0-এও অবস্থিত you আপনি পুনরাবৃত্তি করার সাথে সাথে পরের সূচীতে প্রতিটি উপাদানগুলিকে হ্যাশ টেবিলের সাথে যুক্ত করা হয় কারণ সেখানে তাদের হ্যাশ তাদের রাখার জন্য বলেছে, এবং এটি সর্বদা পরবর্তী সূচকটি পুনরাবৃত্তিটি দেখায়। অপসারণ উপাদানগুলির সংঘর্ষের সমাধানের উদ্দেশ্যে, তাদের পুরানো অবস্থানে একটি ডামি চিহ্নিতকারী রয়েছে। আপনি এটি প্রয়োগ করা দেখতে পারেন set_discard_entry
:
entry = set_lookkey(so, key, hash);
if (entry == NULL)
return -1;
if (entry->key == NULL)
return DISCARD_NOTFOUND;
old_key = entry->key;
entry->key = dummy;
entry->hash = -1;
so->used--;
Py_DECREF(old_key);
return DISCARD_FOUND;
যখন 4
সেটে যুক্ত করা হয়, তখন সেটে উপাদান এবং ডামির সংখ্যা পর্যাপ্ত পরিমাণে হয়ে যায় যা set_add_entry
একটি হ্যাশ টেবিল পুনর্নির্মাণকে ট্রিগার করে set_table_resize
:
if ((size_t)so->fill*5 < mask*3)
return 0;
return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
so->used
হ্যাশ টেবিলের জনবহুল, নন-ডামি এন্ট্রিগুলির সংখ্যা, যা 2, সুতরাং set_table_resize
এটি দ্বিতীয় আর্গুমেন্ট হিসাবে 8 পায়। এর ভিত্তিতে, নতুন হ্যাশ টেবিলের আকার 16 হওয়া উচিত set_table_resize
সিদ্ধান্ত নেয় :
/* Find the smallest table size > minused. */
/* XXX speed-up with intrinsics */
size_t newsize = PySet_MINSIZE;
while (newsize <= (size_t)minused) {
newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
}
এটি আকারের 16 এর সাথে হ্যাশ টেবিলটি পুনর্নির্মাণ করে elements সমস্ত হ্যাশ টেবিলের পুরাতন সূচীতে এখনও শেষ হয়, কারণ তাদের হ্যাশগুলিতে কোনও উচ্চ বিট সেট ছিল না।
লুপটি চলতে থাকায়, উপাদানগুলি পরবর্তী সূচকটিতে পুনরাবৃত্তকারীটি দেখতে পাবে। আরেকটি হ্যাশ টেবিল পুনর্নির্মাণটি ট্রিগার করা হয়েছে, তবে নতুন আকারটি এখনও 16।
যখন উপাদান হিসাবে লুপটি 16 যোগ করে তখন প্যাটার্নটি ভেঙে যায়। নতুন উপাদানটি রাখতে কোনও সূচক 16 নেই। 16 টির 4 টি সর্বনিম্ন বিটগুলি 0000 হয়, 16 টি সূচক 0 এ বসায় পুনরুক্তিটির সঞ্চিত সূচকটি এই মুহুর্তে 16 হয় এবং যখন লুপটি পুনরুক্তি থেকে পরবর্তী উপাদানটির জন্য জিজ্ঞাসা করে, পুনরুক্তিটি দেখতে পায় যে এটি শেষের শেষে চলে গেছে হ্যাশ টেবিল.
পুনরুক্তিকারী কেবলমাত্র 16
সেটে রেখে এই সময়ে লুপটি সমাপ্ত করে ।
s.add(i+1)
(এবং সম্ভবত, কল করতেs.remove(i)
) সেটটির পুনরাবৃত্তির ক্রম পরিবর্তন করতে পারে, লুপের জন্য তৈরি সেট পুনরুদ্ধারটি পরবর্তীটি কী দেখবে তা প্রভাবিত করে। আপনার একটি সক্রিয় পুনরাবৃত্তি করার সময় কোনও বস্তুর রূপান্তর করবেন না।