python中dict怎么查找_Python中Dict的查找

Dict的类型的查找使用的是lookdict函数

static PyDictKeyEntry *lookdict(PyDictObject*mp, PyObject *key,

Py_hash_t hash, PyObject***value_addr)

函数的参数中,*value_addr是指向匹配slot中值的指针。 这个函数在正确的情况下一定会返回一个指向slot的指针,出错则会返回NULL。 如果成功找到了匹配的slot,则返回对应的slot; 如果没有匹配的slot,则返回查找链上第一个未被使用的slot。 该slot可以是unused状态,也可以是dummy状态。

mask = DK_MASK(mp->ma_keys);

ep0= &mp->ma_keys->dk_entries[0];

i= (size_t)hash & mask;

计算了slot的初始位置,把hash值映射到slot table的下标范围内。 初始位置=hash&mask,mask=dk_size-1

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

}

如果找到了匹配的key或unused slot,返回该结果即可。

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)returnNULL;if (ep0 == mp->ma_keys->dk_entries && ep->me_key ==startkey) {if (cmp > 0) {*value_addr = &ep->me_value;returnep;

}

}else{/*The dict was mutated, restart*/

gototop;

}

}

freeslot=NULL;

}

进一步的比较。 若该slot状态为dummy,则用freeslot记录该slot并继续搜索; 如果该slot的hash值与待搜索key的hash相同,那么对两个key进行比较。 这里的PyObject_RichCompareBool是一个比较函数,其第三个参数为比较的操作。 如果操作结果为true,返回1;为false,返回0;比较出错,返回-1。 比较出错的情况下会返回NULL,比较成功(在这里为相等)返回该slot,比较不成功则继续进行搜索。 这一部分进行了第一次的搜索;在dict容量不太满时,一般在这里就可以找到合适的结果。

i = (i << 2) + i + perturb + 1;

ep= &ep0[i &mask];if (ep->me_key ==NULL) {if (freeslot ==NULL) {*value_addr = &ep->me_value;returnep;

}else{*value_addr = &freeslot->me_value;returnfreeslot;

}

}

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

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

}

找到了匹配的key。此情况返回对应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;returnNULL;

}if (ep0 == mp->ma_keys->dk_entries && ep->me_key ==startkey) {if (cmp > 0) {*value_addr = &ep->me_value;returnep;

}

}else{/*The dict was mutated, restart*/

gototop;

}

}

该slot hash值与给定hash值相同时进一步比较的情况。

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

freeslot= ep;

在dummy情况下设置freeslot。

在搜索过程中,原则是找到和key相等的对象即可。 那么什么是和key相等呢? 一种情况是它们的引用相等,自然的值也相等。 这类比较只需要直接比较对应指针是否相等呢该即可。 而另一种情况是引用不相等,但值还相等。 如果没有对这种情况的处理,那么对于非共享的对象来说搜索几乎不会得到正确的结果。 搜索中的进一步比较就是对这种情况的处理。 进一步比较发生的前提是hash值相等,因为值相等必然有hash相等, 但hash相等值却可能不等,因此不能直接比较hash值,还需要更进一步的比较值才可以。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值