用 C 扩展 python:尝试交换列表元素

Extending python with C: trying to swap list elements

我要为 Python 3.7 构建一个 C 模块,它交换两个列表元素。 这是我的代码,其中读取了两个元素和列表的索引:

static PyObject *st_change(PyObject *self, PyObject *args){
  PyObject *pList;
  PyObject *tmp1;
  PyObject *tmp2;
  int i,j;
  Py_ssize_t n;

  if (!PyArg_ParseTuple(args, "O!ll", &PyList_Type, &pList,&i,&j)) {
    PyErr_SetString(PyExc_TypeError, "parameters are wrong.");
    return NULL;
    }

  n = PyList_Size(pList);
  tmp1 = PyList_GetItem(pList,i);       
  tmp2 = PyList_GetItem(pList,j);
  PyList_SetItem(pList,i,tmp2);
  PyList_SetItem(pList,j,tmp1);
  Py_INCREF(pList);

  return pList;
}

这适用于一维列表,但当我尝试交换列表列表中的元素时,Python 关闭。 例如,当调用

my_module.st_change([1,2,3],0,1)

结果是

[2,1,3]

当我打电话给

my_module.st_change([[1,2,3],[4,5,6],[7,8,9]],0,1)

python shell 休息

我完全不熟悉 C Python API,如果有人能指出正确的方向,我将不胜感激。谢谢

您正在丢失对 tmp1 的引用。 PyList_SetItem discards a reference to the item already in that position,因此当您执行 PyList_SetItem(pList,i,tmp2); 时,您 tmp1 会被取消并可能被释放。 int 你不用管它,因为通常有很多对小 int 值的引用。

在调用 PyList_SetItem 之前添加 Py_INCREF(tmp1); Py_INCREF(tmp2);