Reputation: 1099
I am writing a Python C extension. I am passing a Python dict
to a C function. I am able to parse it, using the following code:
PyObject *large_dict = NULL;
if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &large_dict)) return NULL;
if (large_dict != NULL)
{
printf("Large Dictionary Not Null\n");
}
Here the statement "Large Dictionary Not Null" is printed, which means that the dictionary is parsed successfully.
Now I want to access the dictionary values by specifying keys, like we do in Python. For example, large_dict['k1']
would give value v1
.
How can I access dictionary keys/values inside this C function?
Upvotes: 7
Views: 6465
Reputation: 2382
I'll reply for Python 3.7+, since that's the most likely use case these days (see reference). Converting from/to C types is dependent on the Python type of the keys/values, which you haven't specified. For the sake of illustrating an actual use-case, let's assume the keys and values are both positive integers. Then if you want to retrieve the value for k1=42
then I think you can do this:
unsigned int k1 = 42;
PyObject *py_k1 = PyLong_FromUnsignedLong(k1);
PyObject *py_v1 = PyDict_GetItem(large_dict, py_k1);
unsigned int v1 = PyLong_AsUnsignedLong(py_v1);
Breaking this down line by line, the first line defines the key as a plain C unsigned int
. But we can't use a regular C type to index into a Python dict, therefore in the second line we define a pointer to a Python type that will point to the key. We then do the C equivalent of Python's large_dict[k1]
via PyDict_GetItem
, but using the pointer we created as the key and obtaining a pointer to a Python type as the value. Finally, if we want to access the value as a regular C type, we need to convert it in the last line, which is the reverse of what we did in the second line.
Note: PyDict_GetItem
returns a borrowed reference, so we don't need to worry about reference counting.
Upvotes: 0
Reputation: 1966
You should go through the link, https://docs.python.org/2/c-api/dict.html Excerpt given below,
PyObject* PyDict_GetItem(PyObject *p, PyObject *key)
Return value: Borrowed reference.
Return the object from dictionary p which has a key key. Return NULL if the key key is not present, but without setting an exception.
PyObject* PyDict_GetItemString(PyObject *p, const char *key)
Return value: Borrowed reference.
This is the same as PyDict_GetItem(), but key is specified as a char*, rather than a PyObject*.
PyObject* PyDict_Items(PyObject *p)
Return value: New reference.
Return a PyListObject containing all the items from the dictionary, as in the dictionary method dict.items().
PyObject* PyDict_Keys(PyObject *p)
Return value: New reference.
Return a PyListObject containing all the keys from the dictionary, as in the dictionary method dict.keys().
PyObject* PyDict_Values(PyObject *p)
Return value: New reference.
Return a PyListObject containing all the values from the dictionary p, as in the dictionary method dict.values().
Keep an eye on borrowed reference / new reference
. It is little tricky while coding for Python extensions.
Upvotes: 5