En Thu, 08 Mar 2007 22:26:59 -0300, ZiZi Zhao <[EMAIL PROTECTED]> escribió:

> I tried to build a list of dictionaries using embedded Python2.5
> in the following way to append dictionaries to a list.
>
> Py_Object *pList = PyList_New(0);
>
> for (i=0; i<MAXSIZE; i++) {
>     Py_Object *pDict = PyDict_New();
>     //
>     // build this dictionary of keys & values
>     //
>     if (pDict != NULL) {
>         if (PyList_Append(pList, pDict) < 0) {
>             printf ("Failed to append new dict to dict-list\n");
>         }
>         Py_DECREF(pDict);
>     }
> }
>
> In this way, I found the PyList_Append only appends the pointer
> of pDict to pList.

All Python objects are seen as pointers on C code.

> After Py_DECREF(pDict) and going back to,
> Py_Object *pDict = PyDict_New();
> for next run in loop, it gets the same pointer as last time,

Perhaps (in the non-posted block) there is a Py_INCREF missing, and that  
last Py_DECREF destroys the object.
(You don't see the printf message, I presume)

> which finally makes all dictionaries in the list are the same
> as the last one. (BTW, in Python, the result is correct.)
> Now, I have to do no Py_DECREF(pDict) in the loop, but do once at
> the end, when the loop is finished, like

You could check using sys.getrefcount; if all of them say 2 (including the  
last dict) you know the list holds the only reference to them. (And all  
id() should be different, too).

Maybe this code is useful; builds a list of empty dictionaries. (Note that  
I *know* the list is empty and has the right size, so I can use  
PyList_SET_ITEM instead of the non-macro version PyList_SetItem or the  
insert/append variants).


/*
  flistdict - fast list of dictionaries
  flistdict(size) -> [{},{},...] = [{} for _ in range(size)]
  Devuelve una lista de diccionarios vacíos (todos diferentes)
*/
static PyObject *
flistdict(PyObject *self, PyObject *args)
{
     int i, size;
     PyObject *result=NULL, *dict=NULL;

     if (!PyArg_ParseTuple(args, "i", &size))
         return NULL;
     result = PyList_New(size);
     if (result==NULL)
         goto error;
     for (i=0; i<size; i++) {
         dict = PyDict_New();
         if (dict==NULL)
              goto error;
         PyList_SET_ITEM(result, i, dict);
     }
     goto normalexit;

error:
     Py_XDECREF(result);
     result = NULL;

normalexit:
     return result;
}

-- 
Gabriel Genellina

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to