zoukankan      html  css  js  c++  java
  • Python源码:字典

    一、创建增加修改

    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}

    二、删除(del)

    1、实现代码

    del stu_info["chenqun"]
    print(stu_info)
    

    2、输出结果

    {'xiedi': 29, 'liuhailin': 27, 'daiqiao': 30, 'hanwenhai': 25, 'luoahong': 32}

     1、Dict_DelItem 

    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);
    }
    

    2、Dict_DelItem_KnownHash

    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.
     */
    

    3、PyDict_DelItemIf

    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;
    }
    

    二、删除pop(k)

    实现

    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}
    

    1、_PyDict_Pop

    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);
    }

    2、_PyDict_Pop_KnownHash

    /* 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;
    }

    三、随机删除一个元素popitem()

    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}
    

    1、dict_popitem_impl

    /*[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;
    }
    

    四、查找(key值在字典中存在) 

    1、dict_keys

    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;
    }
    

    2、PyDict_Keys

    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);
    }

    五、get(k)

    1、dict_get_impl

    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;
    }

    2、_PyDict_GetItem_KnownHash

    /* 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;
    }
    

    3、_PyDict_GetItemId

    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 */
    
    

    4、PyDict_GetItemString

    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(k,v)

    setdefault()表示去取字典中的key,如果取不到,则设置新值,相反如果取到,则返回原有默认值

    1、dict_setdefault_impl 

    /*[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
        /
    

    2、PyDict_SetDefault

    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(dict)

    update()是把两个字典合并成一个新的字典,中间有交叉的key,更新替换成新值,没有交叉就直接创建

    1、dict_update_common

    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;
    }

    2、dict_update

    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.
    */
    

    3、PyDict_Update

    int
    PyDict_Update(PyObject *a, PyObject *b)
    {
        return dict_merge(a, b, 1);
    }
    

    八、items()将字典转换为列表

    1、PyDict_Items

    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.
     */
    

    九、fromkeys(list,默认值)

    1、_PyDict_FromKeys

    /* 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;
    }
    

    2、dict_fromkeys_impl

    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. */
    

    十、Clea清空字典

    1、PyDict_ClearFreeList

    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;
    }
    

    2、PyDict_Clea

    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);
    }
    

    3、dict_clear

    static PyObject *
    dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
    {
        PyDict_Clear((PyObject *)mp);
        Py_RETURN_NONE;
    }
    

    4、dict_tp_clear

    static int
    dict_tp_clear(PyObject *op)
    {
        PyDict_Clear(op);
        return 0;
    }
  • 相关阅读:
    mysql索引
    mysql主从复制(同步)
    MySQL事务与锁
    四大高阶函数
    客户端、服务端通信值统计字符串个数【网络程序设计
    《Unicast QoS Routing Algorithms for SDN Survey 2018》【毕设
    CDQ分治【待补充,数据结构
    KD树学习小结【待补充,数据结构
    线段树模板【数据结构
    【牛客网】牛客练习赛19 F 算式子【数学--递推 、前缀、数字】
  • 原文地址:https://www.cnblogs.com/luoahong/p/12037106.html
Copyright © 2011-2022 走看看