日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python中Dict的查找

發(fā)布時(shí)間:2023/12/1 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中Dict的查找 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Dict的類型的查找使用的是lookdict函數(shù)

static PyDictKeyEntry * lookdict(PyDictObject *mp, PyObject *key,Py_hash_t hash, PyObject ***value_addr)

函數(shù)的參數(shù)中,*value_addr是指向匹配slot中值的指針。 這個(gè)函數(shù)在正確的情況下一定會(huì)返回一個(gè)指向slot的指針,出錯(cuò)則會(huì)返回NULL。 如果成功找到了匹配的slot,則返回對(duì)應(yīng)的slot; 如果沒有匹配的slot,則返回查找鏈上第一個(gè)未被使用的slot。 該slot可以是unused狀態(tài),也可以是dummy狀態(tài)。

mask = DK_MASK(mp->ma_keys);ep0 = &mp->ma_keys->dk_entries[0];i = (size_t)hash & mask;

計(jì)算了slot的初始位置,把hash值映射到slot table的下標(biāo)范圍內(nèi)。 初始位置=hash&mask,mask=dk_size-1

if (ep->me_key == NULL || ep->me_key == key) {*value_addr = &ep->me_value;return ep;}

如果找到了匹配的key或unused slot,返回該結(jié)果即可。

if (ep->me_key == dummy)freeslot = ep;else {if (ep->me_hash == hash) {startkey = ep->me_key;Py_INCREF(startkey);cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);Py_DECREF(startkey);if (cmp < 0)return NULL;if (ep0 == mp->ma_keys->dk_entries && ep->me_key == startkey) {if (cmp > 0) {*value_addr = &ep->me_value;return ep;}}else {/* The dict was mutated, restart */goto top;}}freeslot = NULL;}

進(jìn)一步的比較。 若該slot狀態(tài)為dummy,則用freeslot記錄該slot并繼續(xù)搜索; 如果該slot的hash值與待搜索key的hash相同,那么對(duì)兩個(gè)key進(jìn)行比較。 這里的PyObject_RichCompareBool是一個(gè)比較函數(shù),其第三個(gè)參數(shù)為比較的操作。 如果操作結(jié)果為true,返回1;為false,返回0;比較出錯(cuò),返回-1。 比較出錯(cuò)的情況下會(huì)返回NULL,比較成功(在這里為相等)返回該slot,比較不成功則繼續(xù)進(jìn)行搜索。 這一部分進(jìn)行了第一次的搜索;在dict容量不太滿時(shí),一般在這里就可以找到合適的結(jié)果。

i = (i << 2) + i + perturb + 1;ep = &ep0[i & mask];if (ep->me_key == NULL) {if (freeslot == NULL) {*value_addr = &ep->me_value;return ep;} else {*value_addr = &freeslot->me_value;return freeslot;}}

找到了unused slot的情況。 如果freeslot是NULL,那么返回該slot即可;若freeslot不是NULL,那么返回freeslot。

if (ep->me_key == key) {*value_addr = &ep->me_value;return ep;}

找到了匹配的key。此情況返回對(duì)應(yīng)slot即可。

if (ep->me_hash == hash && ep->me_key != dummy) {startkey = ep->me_key;Py_INCREF(startkey);cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);Py_DECREF(startkey);if (cmp < 0) {*value_addr = NULL;return NULL;}if (ep0 == mp->ma_keys->dk_entries && ep->me_key == startkey) {if (cmp > 0) {*value_addr = &ep->me_value;return ep;}}else {/* The dict was mutated, restart */goto top;}}

該slot hash值與給定hash值相同時(shí)進(jìn)一步比較的情況。

else if (ep->me_key == dummy && freeslot == NULL)freeslot = ep;

在dummy情況下設(shè)置freeslot。

?

在搜索過程中,原則是找到和key相等的對(duì)象即可。 那么什么是和key相等呢? 一種情況是它們的引用相等,自然的值也相等。 這類比較只需要直接比較對(duì)應(yīng)指針是否相等呢該即可。 而另一種情況是引用不相等,但值還相等。 如果沒有對(duì)這種情況的處理,那么對(duì)于非共享的對(duì)象來說搜索幾乎不會(huì)得到正確的結(jié)果。 搜索中的進(jìn)一步比較就是對(duì)這種情況的處理。 進(jìn)一步比較發(fā)生的前提是hash值相等,因?yàn)橹迪嗟缺厝挥衕ash相等, 但hash相等值卻可能不等,因此不能直接比較hash值,還需要更進(jìn)一步的比較值才可以。

轉(zhuǎn)載于:https://www.cnblogs.com/ruizhang3/p/6888006.html

總結(jié)

以上是生活随笔為你收集整理的Python中Dict的查找的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。