I was wondering if this was possible to iterate through a map directly in Cython
code, ie, in the .pyx
.
Here is my example:
import cython
cimport cython
from licpp.map import map as mapcpp
def it_through_map(dict mymap_of_int_int):
# python dict to map
cdef mapcpp[int,int] mymap_in = mymap_of_int_int
cdef mapcpp[int,int].iterator it = mymap_in.begin()
while(it != mymap.end()):
# let's pretend here I just want to print the key and the value
print(it.first) # Not working
print(it.second) # Not working
it ++ # Not working
This does not compile: Object of type 'iterator' has no attribute 'first'
I used map container in cpp before but for this code, I am trying to stick to cython/python, is it possible here?.
Resolved by DavidW Here is an working version of the code, following DavidW answer:
import cython
cimport cython
from licpp.map import map as mapcpp
from cython.operator import dereference, postincrement
def it_through_map(dict mymap_of_int_int):
# python dict to map
cdef mapcpp[int,int] mymap_in = mymap_of_int_int
cdef mapcpp[int,int].iterator it = mymap_in.begin()
while(it != mymap.end()):
# let's pretend here I just want to print the key and the value
print(dereference(it).first) # print the key
print(dereference(it).second) # print the associated value
postincrement(it) # Increment the iterator to the net element
The map iterator doesn't have elements first
and second
. Instead it has a operator*
which returns a pair
reference. In C++ you can use it->first
to do this in one go, but that syntax doesn't work in Cython (and it isn't intelligent enough to decide to use ->
instead of .
itself in this case).
Instead you use cython.operator.dereference
:
from cython.operator cimport dereference
# ...
print(dereference(it).first)
Similarly, it++
can be done with cython.operator.postincrement
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With