Passing list with flexible length to C extension
Fredrik Lundh
fredrik at pythonware.com
Fri Nov 21 08:23:43 EST 2003
Bostjan Jerko wrote:
> Is there a way to pass list with flexible length to C extension?
> I want to pass flexible length list of floats to method and just can't get info
> if it is possible and how to do it.
use a PyObject* variable to hold the list object (use "O" for the type
code), and use the sequence API to loop over the list contents:
http://www.python.org/doc/current/api/sequence.html
unless your sequences are really large, the PySequence_Fast API is the
most efficient way to extract the items (it applies tuple() to the source,
unless it's already a tuple or a list, and uses direct access to the object
structure to pick out individual items):
...
PyObject* obj;
PyObject* seq;
int i, len;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
seq = PySequence_Fast(obj, type_error_msg);
len = PySequence_Size(obj);
for (i = 0; i < len; i++) {
item = PySequence_Fast_GET_ITEM(seq, i);
...
/* DON'T DECREF item here */
}
Py_DECREF(seq);
...
you'll find plenty of examples in the source code for the standard library
grep for PySequence and look for GetItem, GET_ITEM, and Fast_GET_ITEM
calls...)
you can also use the PyList API, but that only works for lists, and is only
marginally faster than the PySequence_Fast API.
http://www.python.org/doc/current/api/listObjects.html
(to squeeze out the last cycles from PySequence_Fast, expand the loop
body yourself:
seq = PySequence_Fast(obj, type_error_msg);
len = PySequence_Size(obj);
if (PyList_Check(seq))
for (i = 0; i < len; i++) {
item = PyList_GET_ITEM(seq, i);
...
}
else
for (i = 0; i < len; i++) {
item = PyTuple_GET_ITEM(seq, i);
...
}
Py_DECREF(seq);
this design is as fast as a list-only implementation, but still supports
tuples (fast) and other sequence objects, including arbitrary iterable
objects (slower)).
</F>
More information about the Python-list
mailing list