How to manipulate C table as python list ?

Hi,
I would like to use a C program which manipulates table as a python module acting on a list. My C code is the following: int sum(int *tab, int n) { int i, s = 0;
for (i=0; i<n; i++) { s += tab[i]; }
return s; } Now, I would like to use it as a python module where tab would be a python list. I read some examples in the documentation but the size of the list is always assumed to be known such that one can use PyArg_ParseTuple with a format description for each argument. I would like that my module behave like: a=[1,2,3] b=[2,8,20] print my_module.sum(a) -> 6 print my_module.sum(b) -> 30
My question is: which option should I use with PyArg_ParseTuple? I'm totaly lost with all its option (O, O&, O!, etc)
Thx, Marc.

Marc marcglec@free.fr writes:
I would like to use a C program which manipulates table as a python module acting on a list. My C code is the following: int sum(int *tab, int n) { int i, s = 0;
for (i=0; i<n; i++) { s += tab[i]; }
return s; } Now, I would like to use it as a python module where tab would be a python list. I read some examples in the documentation but the size of the list is always assumed to be known such that one can use PyArg_ParseTuple with a format description for each argument.
In this case you only use PyArg_ParseTuple to get to the object that represents the list. In fact, since you only need one argument, you don't need PyArg_ParseTuple at all, simply declare your function to take one argument using the METH_O in the function description, and code it like this:
PyObject *sum(PyObject *ignored, PyObject *lst) { int i, s = 0; if (!PyList_Check(lst)) { PyErr_Format(PyExc_TypeError, "sum: expected list, got %s", lst->ob_type->tp_name); return NULL; } for (i = 0; i < PyList_GET_SIZE(lst); i++) { ... sum the list ... return PyInt_FromLong(s); }
My question is: which option should I use with PyArg_ParseTuple?
If your function is declared to take one argument with METH_O, you don't need PyArg_ParseTuple at all. If it's declared to take a variable number of arguments, you'd use it like this:
PyObject *sum(PyObject *ignored, PyObject *args) { int i, s = 0; PyObject *lst; if (!PyArg_ParseTuple(args, "O", &lst)) return NULL; ... }

Hrvoje Niksic wrote:
PyObject *sum(PyObject *ignored, PyObject *lst) { int i, s = 0; if (!PyList_Check(lst)) { PyErr_Format(PyExc_TypeError, "sum: expected list, got %s", lst->ob_type->tp_name); return NULL; } for (i = 0; i < PyList_GET_SIZE(lst); i++) { ... sum the list ... return PyInt_FromLong(s); }
My question is: which option should I use with PyArg_ParseTuple?
If your function is declared to take one argument with METH_O, you don't need PyArg_ParseTuple at all. If it's declared to take a variable number of arguments, you'd use it like this:
PyObject *sum(PyObject *ignored, PyObject *args) { int i, s = 0; PyObject *lst; if (!PyArg_ParseTuple(args, "O", &lst)) return NULL; ... }
You can also write your code in Cython. The following Cython code will generate roughly the same C code that you present above:
def sum(list l):
cdef int i, s = 0
for i in l:
s += i
return s
Stefan

Thx to all for your answers, I'm sure I will succeed now :)
Marc.
Le dimanche 18 janvier 2009 à 09:51 +0100, Hrvoje Niksic a écrit :
Marc marcglec@free.fr writes:
I would like to use a C program which manipulates table as a python module acting on a list. My C code is the following: int sum(int *tab, int n) { int i, s = 0;
for (i=0; i<n; i++) { s += tab[i]; }
return s; } Now, I would like to use it as a python module where tab would be a python list. I read some examples in the documentation but the size of the list is always assumed to be known such that one can use PyArg_ParseTuple with a format description for each argument.
In this case you only use PyArg_ParseTuple to get to the object that represents the list. In fact, since you only need one argument, you don't need PyArg_ParseTuple at all, simply declare your function to take one argument using the METH_O in the function description, and code it like this:
PyObject *sum(PyObject *ignored, PyObject *lst) { int i, s = 0; if (!PyList_Check(lst)) { PyErr_Format(PyExc_TypeError, "sum: expected list, got %s", lst->ob_type->tp_name); return NULL; } for (i = 0; i < PyList_GET_SIZE(lst); i++) { ... sum the list ... return PyInt_FromLong(s); }
My question is: which option should I use with PyArg_ParseTuple?
If your function is declared to take one argument with METH_O, you don't need PyArg_ParseTuple at all. If it's declared to take a variable number of arguments, you'd use it like this:
PyObject *sum(PyObject *ignored, PyObject *args) { int i, s = 0; PyObject *lst; if (!PyArg_ParseTuple(args, "O", &lst)) return NULL; ... }

On 18-Jan-2009, at 01:06 , Marc wrote:
I would like to use a C program which manipulates table as a python module acting on a list.
Marc, if you're doing this for speed you may want to look at Numeric Python <http://numpy.scipy.org/
. They have a set of array-like objects that are (a) pretty standard
from a Python point of view and (b) pretty efficient from a C point of
view. As soon as you're doing serious number crunching the NumPy
arrays will run circles around any code that converts between Python
lists and C arrays, because there isn't any conversion done. NumPy
arrays are used by all sorts of other libraries that have large
numeric datasets (think audio processing, etc).
Also, for the algorithms you've sketched in your example you don't
even have to write any code in C: it's all there in NumPy already.
--
Jack Jansen, Jack.Jansen@cwi.nl, http://www.cwi.nl/~jack
If I can't dance I don't want to be part of your revolution -- Emma
Goldman
participants (4)
-
Hrvoje Niksic
-
Jack Jansen
-
Marc
-
Stefan Behnel