Defining and using a vector of maps in cython (using libcpp)

1,300 views
Skip to first unread message

Raghav R V

unread,
Mar 17, 2016, 8:13:49 AM3/17/16
to cython-users
Hi,

I need to store a list of dictionaries in cython and decided to go with the `vector[map[string, int]]` setup as I don't know the size of the list.

Currently I'm trying the below

%%cython

# distutils: language = c++

from libcpp.string cimport string
from libcpp.map cimport map
from libcpp.vector cimport vector

cdef vector[map[string, int]] categories
cdef map[string, int]* categories_i

for i in range(2):
    categories_i = new map[string, int]
    categories_i[<string>'foo'] = 1
    categories_i[<string>'bar'] = 2
    categories.pushback(categories_i)

print categories[0][<string>'foo']

But I get a 

"Expected an identifier before '='" error... I understand that the error stems from the creation of the new map object (categories_i = new map[string, int]) but unsure how I should proceed.

Or is there an easier way to declare and use the python equivalent of list of dicts in cython?

Thanks,

R

Raghav R V

unread,
Mar 25, 2016, 12:44:36 PM3/25/16
to cython-users
Just letting you know that I've figured it out! (Wanted to post this the other day itself, but my original post was not approved at that time. So posting this now!)

I had to instantiate - 

    categories_i = new cpp_hashmap[string, int]()

And dereference the pointer

    categories_i[0][<string>'foo'] = 1
    categories_i[0][<string>'bar'] = 2
    categories.push_back(categories_i[0])
    del categories_i

Now it works as expected.

>>> print categories_i[0][<string>'foo']
1

Thanks,

R

Robert Bradshaw

unread,
Mar 25, 2016, 1:07:30 PM3/25/16
to cython...@googlegroups.com
On Fri, Mar 25, 2016 at 6:18 AM, Raghav R V <rvrag...@gmail.com> wrote:
Just letting you know that I've figured it out! (Wanted to post this the other day itself, but my original post was not approved at that time. So posting this now!)

I had to instantiate - 

    categories_i = new cpp_hashmap[string, int]()

And dereference the pointer

    categories_i[0][<string>'foo'] = 1
    categories_i[0][<string>'bar'] = 2
    categories.push_back(categories_i[0])
    del categories_i

Now it works as expected.

>>> print categories_i[0][<string>'foo']


Yep. You could also allocate categories_i on the stack, making sure to clear/reset it every loop iteration. 

from libcpp.string cimport string
from libcpp.map cimport map
from libcpp.vector cimport vector

cdef vector[map[string, int]] categories
cdef map[string, int] categories_i

for i in range(2):
    categories_i = map[string, int]()
Reply all
Reply to author
Forward
0 new messages