当前位置 : 主页 > 编程语言 > python >

Python字典添加,删除,查询等相关操作方法详解

来源:互联网 收集:自由互联 发布时间:2021-04-09
一、创建增加修改 1、实现代码 #创建stu_info = { "xiedi":28, "liuhailin":27,"daiqiao":30,"hanwenhai":25,"chenqun":38}print(stu_info)#增加stu_info["luoahong"]=32print(stu_info)#修改stu_info["xiedi"]=29print(stu_info) 输出结

一、创建增加修改

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

更多关于Python字典添加,删除,查询等相关操作方法的文章请查看下面的相关链接

网友评论