标签:existing merge ide generated char alc fun friend bsp
1、实现代码
#创建 stu_info = { "xiedi":28, "liuhailin":27,"daiqiao":30,"hanwenhai":25,"chenqun":38} print(stu_info) #增加 stu_info["luoahong"]=32 print(stu_info) #修改 stu_info["xiedi"]=29 print(stu_info)
输出结果
{‘xiedi‘: 28, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38} {‘xiedi‘: 28, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38, ‘luoahong‘: 32} {‘xiedi‘: 29, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38, ‘luoahong‘: 32}
1、实现代码
del stu_info["chenqun"] print(stu_info)
2、输出结果
{‘xiedi‘: 29, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘luoahong‘: 32}
int PyDict_DelItem(PyObject *op, PyObject *key) { Py_hash_t hash; assert(key); if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; } return _PyDict_DelItem_KnownHash(op, key, hash); }
int _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { Py_ssize_t ix; PyDictObject *mp; PyObject *old_value; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; } assert(key); assert(hash != -1); mp = (PyDictObject *)op; ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); if (ix == DKIX_ERROR) return -1; if (ix == DKIX_EMPTY || old_value == NULL) { _PyErr_SetKeyError(key); return -1; } // Split table doesn‘t allow deletion. Combine it. if (_PyDict_HasSplitTable(mp)) { if (dictresize(mp, DK_SIZE(mp->ma_keys))) { return -1; } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); assert(ix >= 0); } return delitem_common(mp, hash, ix, old_value); } /* This function promises that the predicate -> deletion sequence is atomic * (i.e. protected by the GIL), assuming the predicate itself doesn‘t * release the GIL. */
int _PyDict_DelItemIf(PyObject *op, PyObject *key, int (*predicate)(PyObject *value)) { Py_ssize_t hashpos, ix; PyDictObject *mp; Py_hash_t hash; PyObject *old_value; int res; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; } assert(key); hash = PyObject_Hash(key); if (hash == -1) return -1; mp = (PyDictObject *)op; ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); if (ix == DKIX_ERROR) return -1; if (ix == DKIX_EMPTY || old_value == NULL) { _PyErr_SetKeyError(key); return -1; } // Split table doesn‘t allow deletion. Combine it. if (_PyDict_HasSplitTable(mp)) { if (dictresize(mp, DK_SIZE(mp->ma_keys))) { return -1; } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); assert(ix >= 0); } res = predicate(old_value); if (res == -1) return -1; hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); if (res > 0) return delitem_common(mp, hashpos, ix, old_value); else return 0; }
实现
stu_info = { "xiedi":28, "liuhailin":27,"daiqiao":30,"hanwenhai":25,"chenqun":38} print(stu_info) stu_info.pop("liuhailin") print(stu_info)
输出结果:
{‘xiedi‘: 28, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38} {‘xiedi‘: 28, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38}
PyObject * _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) { Py_hash_t hash; if (((PyDictObject *)dict)->ma_used == 0) { if (deflt) { Py_INCREF(deflt); return deflt; } _PyErr_SetKeyError(key); return NULL; } if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; } return _PyDict_Pop_KnownHash(dict, key, hash, deflt); }
/* Internal version of dict.pop(). */ PyObject * _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt) { Py_ssize_t ix, hashpos; PyObject *old_value, *old_key; PyDictKeyEntry *ep; PyDictObject *mp; assert(PyDict_Check(dict)); mp = (PyDictObject *)dict; if (mp->ma_used == 0) { if (deflt) { Py_INCREF(deflt); return deflt; } _PyErr_SetKeyError(key); return NULL; } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); if (ix == DKIX_ERROR) return NULL; if (ix == DKIX_EMPTY || old_value == NULL) { if (deflt) { Py_INCREF(deflt); return deflt; } _PyErr_SetKeyError(key); return NULL; } // Split table doesn‘t allow deletion. Combine it. if (_PyDict_HasSplitTable(mp)) { if (dictresize(mp, DK_SIZE(mp->ma_keys))) { return NULL; } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); assert(ix >= 0); } hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); assert(old_value != NULL); mp->ma_used--; mp->ma_version_tag = DICT_NEXT_VERSION(); dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); ep = &DK_ENTRIES(mp->ma_keys)[ix]; ENSURE_ALLOWS_DELETIONS(mp); old_key = ep->me_key; ep->me_key = NULL; ep->me_value = NULL; Py_DECREF(old_key); ASSERT_CONSISTENT(mp); return old_value; }
stu_info = { "xiedi":28, "liuhailin":27,"daiqiao":30,"hanwenhai":25,"chenqun":38} print(stu_info) stu_info.popitem() print(stu_info)
输出结果:
{‘xiedi‘: 28, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25, ‘chenqun‘: 38} {‘xiedi‘: 28, ‘liuhailin‘: 27, ‘daiqiao‘: 30, ‘hanwenhai‘: 25}
/*[clinic input] dict.popitem Remove and return a (key, value) pair as a 2-tuple. Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty. [clinic start generated code]*/ static PyObject * dict_popitem_impl(PyDictObject *self) /*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/ { Py_ssize_t i, j; PyDictKeyEntry *ep0, *ep; PyObject *res; /* Allocate the result tuple before checking the size. Believe it * or not, this allocation could trigger a garbage collection which * could empty the dict, so if we checked the size first and that * happened, the result would be an infinite loop (searching for an * entry that no longer exists). Note that the usual popitem() * idiom is "while d: k, v = d.popitem()". so needing to throw the * tuple away if the dict *is* empty isn‘t a significant * inefficiency -- possible, but unlikely in practice. */ res = PyTuple_New(2); if (res == NULL) return NULL; if (self->ma_used == 0) { Py_DECREF(res); PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty"); return NULL; } /* Convert split table to combined table */ if (self->ma_keys->dk_lookup == lookdict_split) { if (dictresize(self, DK_SIZE(self->ma_keys))) { Py_DECREF(res); return NULL; } } ENSURE_ALLOWS_DELETIONS(self); /* Pop last item */ ep0 = DK_ENTRIES(self->ma_keys); i = self->ma_keys->dk_nentries - 1; while (i >= 0 && ep0[i].me_value == NULL) { i--; } assert(i >= 0); ep = &ep0[i]; j = lookdict_index(self->ma_keys, ep->me_hash, i); assert(j >= 0); assert(dictkeys_get_index(self->ma_keys, j) == i); dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY); PyTuple_SET_ITEM(res, 0, ep->me_key); PyTuple_SET_ITEM(res, 1, ep->me_value); ep->me_key = NULL; ep->me_value = NULL; /* We can‘t dk_usable++ since there is DKIX_DUMMY in indices */ self->ma_keys->dk_nentries = i; self->ma_used--; self->ma_version_tag = DICT_NEXT_VERSION(); ASSERT_CONSISTENT(self); return res; }
static PyObject * dict_keys(PyDictObject *mp) { PyObject *v; Py_ssize_t i, j; PyDictKeyEntry *ep; Py_ssize_t n, offset; PyObject **value_ptr; again: n = mp->ma_used; v = PyList_New(n); if (v == NULL) return NULL; if (n != mp->ma_used) { /* Durnit. The allocations caused the dict to resize. * Just start over, this shouldn‘t normally happen. */ Py_DECREF(v); goto again; } ep = DK_ENTRIES(mp->ma_keys); if (mp->ma_values) { value_ptr = mp->ma_values; offset = sizeof(PyObject *); } else { value_ptr = &ep[0].me_value; offset = sizeof(PyDictKeyEntry); } for (i = 0, j = 0; j < n; i++) { if (*value_ptr != NULL) { PyObject *key = ep[i].me_key; Py_INCREF(key); PyList_SET_ITEM(v, j, key); j++; } value_ptr = (PyObject **)(((char *)value_ptr) + offset); } assert(j == n); return v; }
PyObject * PyDict_Keys(PyObject *mp) { if (mp == NULL || !PyDict_Check(mp)) { PyErr_BadInternalCall(); return NULL; } return dict_keys((PyDictObject *)mp); } PyObject * PyDict_Values(PyObject *mp) { if (mp == NULL || !PyDict_Check(mp)) { PyErr_BadInternalCall(); return NULL; } return dict_values((PyDictObject *)mp); }
static PyObject * dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) /*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/ { PyObject *val = NULL; Py_hash_t hash; Py_ssize_t ix; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; } ix = (self->ma_keys->dk_lookup) (self, key, hash, &val); if (ix == DKIX_ERROR) return NULL; if (ix == DKIX_EMPTY || val == NULL) { val = default_value; } Py_INCREF(val); return val; }
/* Same as PyDict_GetItemWithError() but with hash supplied by caller. This returns NULL *with* an exception set if an exception occurred. It returns NULL *without* an exception set if the key wasn‘t present. */ PyObject * _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { Py_ssize_t ix; PyDictObject *mp = (PyDictObject *)op; PyObject *value; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return NULL; } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); if (ix < 0) { return NULL; } return value; }
PyObject * _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key) { PyObject *kv; kv = _PyUnicode_FromId(key); /* borrowed */ if (kv == NULL) { PyErr_Clear(); return NULL; } return PyDict_GetItem(dp, kv); } /* For backward compatibility with old dictionary interface */
PyObject * PyDict_GetItemString(PyObject *v, const char *key) { PyObject *kv, *rv; kv = PyUnicode_FromString(key); if (kv == NULL) { PyErr_Clear(); return NULL; } rv = PyDict_GetItem(v, kv); Py_DECREF(kv); return rv; } int _PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item) { PyObject *kv; kv = _PyUnicode_FromId(key); /* borrowed */ if (kv == NULL) return -1; return PyDict_SetItem(v, kv, item); } int PyDict_SetItemString(PyObject *v, const char *key, PyObject *item) { PyObject *kv; int err; kv = PyUnicode_FromString(key); if (kv == NULL) return -1; PyUnicode_InternInPlace(&kv); /* XXX Should we really? */ err = PyDict_SetItem(v, kv, item); Py_DECREF(kv); return err; }
setdefault()表示去取字典中的key,如果取不到,则设置新值,相反如果取到,则返回原有默认值
/*[clinic input] dict.setdefault key: object default: object = None / Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. [clinic start generated code]*/ static PyObject * dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *default_value) /*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/ { PyObject *val; val = PyDict_SetDefault((PyObject *)self, key, default_value); Py_XINCREF(val); return val; } static PyObject * dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { PyDict_Clear((PyObject *)mp); Py_RETURN_NONE; } /*[clinic input] dict.pop key: object default: object = NULL /
PyObject * PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) { PyDictObject *mp = (PyDictObject *)d; PyObject *value; Py_hash_t hash; if (!PyDict_Check(d)) { PyErr_BadInternalCall(); return NULL; } if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; } if (mp->ma_keys == Py_EMPTY_KEYS) { if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) { return NULL; } return defaultobj; } if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { if (insertion_resize(mp) < 0) return NULL; } Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); if (ix == DKIX_ERROR) return NULL; if (_PyDict_HasSplitTable(mp) && ((ix >= 0 && value == NULL && mp->ma_used != ix) || (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { if (insertion_resize(mp) < 0) { return NULL; } ix = DKIX_EMPTY; } if (ix == DKIX_EMPTY) { PyDictKeyEntry *ep, *ep0; value = defaultobj; if (mp->ma_keys->dk_usable <= 0) { if (insertion_resize(mp) < 0) { return NULL; } } Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); ep0 = DK_ENTRIES(mp->ma_keys); ep = &ep0[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); Py_INCREF(key); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); ep->me_key = key; ep->me_hash = hash; if (_PyDict_HasSplitTable(mp)) { assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL); mp->ma_values[mp->ma_keys->dk_nentries] = value; } else { ep->me_value = value; } mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); } else if (value == NULL) { value = defaultobj; assert(_PyDict_HasSplitTable(mp)); assert(ix == mp->ma_used); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); mp->ma_values[ix] = value; mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); } ASSERT_CONSISTENT(mp); return value; }
update()是把两个字典合并成一个新的字典,中间有交叉的key,更新替换成新值,没有交叉就直接创建
static int dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, const char *methname) { PyObject *arg = NULL; int result = 0; if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) { result = -1; } else if (arg != NULL) { if (PyDict_CheckExact(arg)) { result = PyDict_Merge(self, arg, 1); } else { _Py_IDENTIFIER(keys); PyObject *func; if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { result = -1; } else if (func != NULL) { Py_DECREF(func); result = PyDict_Merge(self, arg, 1); } else { result = PyDict_MergeFromSeq2(self, arg, 1); } } } if (result == 0 && kwds != NULL) { if (PyArg_ValidateKeywordArguments(kwds)) result = PyDict_Merge(self, kwds, 1); else result = -1; } return result; }
static PyObject * dict_update(PyObject *self, PyObject *args, PyObject *kwds) { if (dict_update_common(self, args, kwds, "update") != -1) Py_RETURN_NONE; return NULL; } /* Update unconditionally replaces existing items. Merge has a 3rd argument ‘override‘; if set, it acts like Update, otherwise it leaves existing items unchanged. PyDict_{Update,Merge} update/merge from a mapping object. PyDict_MergeFromSeq2 updates/merges from any iterable object producing iterable objects of length 2. */
int PyDict_Update(PyObject *a, PyObject *b) { return dict_merge(a, b, 1); }
PyObject * PyDict_Items(PyObject *mp) { if (mp == NULL || !PyDict_Check(mp)) { PyErr_BadInternalCall(); return NULL; } return dict_items((PyDictObject *)mp); } /* Return 1 if dicts equal, 0 if not, -1 if error. * Gets out as soon as any difference is detected. * Uses only Py_EQ comparison. */
/* Internal version of dict.from_keys(). It is subclass-friendly. */ PyObject * _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) { PyObject *it; /* iter(iterable) */ PyObject *key; PyObject *d; int status; d = _PyObject_CallNoArg(cls); if (d == NULL) return NULL; if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { if (PyDict_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; PyObject *oldvalue; Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { if (insertdict(mp, key, hash, value)) { Py_DECREF(d); return NULL; } } return d; } if (PyAnySet_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { if (insertdict(mp, key, hash, value)) { Py_DECREF(d); return NULL; } } return d; } } it = PyObject_GetIter(iterable); if (it == NULL){ Py_DECREF(d); return NULL; } if (PyDict_CheckExact(d)) { while ((key = PyIter_Next(it)) != NULL) { status = PyDict_SetItem(d, key, value); Py_DECREF(key); if (status < 0) goto Fail; } } else { while ((key = PyIter_Next(it)) != NULL) { status = PyObject_SetItem(d, key, value); Py_DECREF(key); if (status < 0) goto Fail; } } if (PyErr_Occurred()) goto Fail; Py_DECREF(it); return d; Fail: Py_DECREF(it); Py_DECREF(d); return NULL; }
static PyObject * dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) /*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/ { return _PyDict_FromKeys((PyObject *)type, iterable, value); } static int dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, const char *methname) { PyObject *arg = NULL; int result = 0; if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) { result = -1; } else if (arg != NULL) { if (PyDict_CheckExact(arg)) { result = PyDict_Merge(self, arg, 1); } else { _Py_IDENTIFIER(keys); PyObject *func; if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { result = -1; } else if (func != NULL) { Py_DECREF(func); result = PyDict_Merge(self, arg, 1); } else { result = PyDict_MergeFromSeq2(self, arg, 1); } } } if (result == 0 && kwds != NULL) { if (PyArg_ValidateKeywordArguments(kwds)) result = PyDict_Merge(self, kwds, 1); else result = -1; } return result; } /* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention. Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls slower, see the issue #29312. */
int PyDict_ClearFreeList(void) { PyDictObject *op; int ret = numfree + numfreekeys; while (numfree) { op = free_list[--numfree]; assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } while (numfreekeys) { PyObject_FREE(keys_free_list[--numfreekeys]); } return ret; }
void PyDict_Clear(PyObject *op) { PyDictObject *mp; PyDictKeysObject *oldkeys; PyObject **oldvalues; Py_ssize_t i, n; if (!PyDict_Check(op)) return; mp = ((PyDictObject *)op); oldkeys = mp->ma_keys; oldvalues = mp->ma_values; if (oldvalues == empty_values) return; /* Empty the dict... */ dictkeys_incref(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; mp->ma_values = empty_values; mp->ma_used = 0; mp->ma_version_tag = DICT_NEXT_VERSION(); /* ...then clear the keys and values */ if (oldvalues != NULL) { n = oldkeys->dk_nentries; for (i = 0; i < n; i++) Py_CLEAR(oldvalues[i]); free_values(oldvalues); dictkeys_decref(oldkeys); } else { assert(oldkeys->dk_refcnt == 1); dictkeys_decref(oldkeys); } ASSERT_CONSISTENT(mp); }
static PyObject * dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { PyDict_Clear((PyObject *)mp); Py_RETURN_NONE; }
static int dict_tp_clear(PyObject *op) { PyDict_Clear(op); return 0; }
标签:existing merge ide generated char alc fun friend bsp
原文地址:https://www.cnblogs.com/luoahong/p/12037106.html