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

问题描述 投票:0回答:1

我要为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 restsarts

我对C Python API完全陌生,所以如果有人可以向我指出正确的方向,我将不胜感激。谢谢

python-c-api
1个回答
0
投票

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

[呼叫int之前添加PyList_SetItem

© www.soinside.com 2019 - 2024. All rights reserved.