<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7651.59">
<TITLE>RE: list of dictionary in embedded Python</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>You are right! I added<BR>
Py_INCREF(pDict);<BR>
right behind<BR>
pDict = PyDict_New();<BR>
<BR>
it seems to work correctly.<BR>
<BR>
thanks,<BR>
<BR>
zz<BR>
<BR>
-----Original Message-----<BR>
From: python-list-bounces+zzhao=laika.com@python.org on behalf of Gabriel Genellina<BR>
Sent: Thu 3/8/2007 7:15 PM<BR>
To: python-list@python.org<BR>
Subject: Re: list of dictionary in embedded Python<BR>
<BR>
En Thu, 08 Mar 2007 22:26:59 -0300, ZiZi Zhao <zzhao@laika.com> escribió:<BR>
<BR>
> I tried to build a list of dictionaries using embedded Python2.5<BR>
> in the following way to append dictionaries to a list.<BR>
><BR>
> Py_Object *pList = PyList_New(0);<BR>
><BR>
> for (i=0; i<MAXSIZE; i++) {<BR>
>     Py_Object *pDict = PyDict_New();<BR>
>     //<BR>
>     // build this dictionary of keys & values<BR>
>     //<BR>
>     if (pDict != NULL) {<BR>
>         if (PyList_Append(pList, pDict) < 0) {<BR>
>             printf ("Failed to append new dict to dict-list\n");<BR>
>         }<BR>
>         Py_DECREF(pDict);<BR>
>     }<BR>
> }<BR>
><BR>
> In this way, I found the PyList_Append only appends the pointer<BR>
> of pDict to pList.<BR>
<BR>
All Python objects are seen as pointers on C code.<BR>
<BR>
> After Py_DECREF(pDict) and going back to,<BR>
> Py_Object *pDict = PyDict_New();<BR>
> for next run in loop, it gets the same pointer as last time,<BR>
<BR>
Perhaps (in the non-posted block) there is a Py_INCREF missing, and that <BR>
last Py_DECREF destroys the object.<BR>
(You don't see the printf message, I presume)<BR>
<BR>
> which finally makes all dictionaries in the list are the same<BR>
> as the last one. (BTW, in Python, the result is correct.)<BR>
> Now, I have to do no Py_DECREF(pDict) in the loop, but do once at<BR>
> the end, when the loop is finished, like<BR>
<BR>
You could check using sys.getrefcount; if all of them say 2 (including the <BR>
last dict) you know the list holds the only reference to them. (And all <BR>
id() should be different, too).<BR>
<BR>
Maybe this code is useful; builds a list of empty dictionaries. (Note that <BR>
I *know* the list is empty and has the right size, so I can use <BR>
PyList_SET_ITEM instead of the non-macro version PyList_SetItem or the <BR>
insert/append variants).<BR>
<BR>
<BR>
/*<BR>
  flistdict - fast list of dictionaries<BR>
  flistdict(size) -> [{},{},...] = [{} for _ in range(size)]<BR>
  Devuelve una lista de diccionarios vacíos (todos diferentes)<BR>
*/<BR>
static PyObject *<BR>
flistdict(PyObject *self, PyObject *args)<BR>
{<BR>
     int i, size;<BR>
     PyObject *result=NULL, *dict=NULL;<BR>
<BR>
     if (!PyArg_ParseTuple(args, "i", &size))<BR>
         return NULL;<BR>
     result = PyList_New(size);<BR>
     if (result==NULL)<BR>
         goto error;<BR>
     for (i=0; i<size; i++) {<BR>
         dict = PyDict_New();<BR>
         if (dict==NULL)<BR>
              goto error;<BR>
         PyList_SET_ITEM(result, i, dict);<BR>
     }<BR>
     goto normalexit;<BR>
<BR>
error:<BR>
     Py_XDECREF(result);<BR>
     result = NULL;<BR>
<BR>
normalexit:<BR>
     return result;<BR>
}<BR>
<BR>
--<BR>
Gabriel Genellina<BR>
<BR>
--<BR>
<A HREF="http://mail.python.org/mailman/listinfo/python-list">http://mail.python.org/mailman/listinfo/python-list</A><BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>