我在 Python 中有以下代码:
class DisjointSet:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0 for x in range(n)]
def find(self, v):
if v != self.parent[v]:
self.parent[v] = self.find(self.parent[v])
return self.parent[v]
其余代码在“代码复杂度”方面类似,此处不再赘述。
所以我想把上面的代码翻译成cython代码(我懂一点C++,我设法把我所有的代码翻译成C++,但我想试试cython,看看它与c++和python相比如何)。我有类似的东西:
disjointset.pyx:
# distutils: language=c++
from libcpp.vector cimport vector
cdef class DisjointSet:
cpdef public vector[int] parent, rank
def __init__(self, int n):
for i in range(n):
self.parent.push_back(i)
self.rank.push_back(0)
def find(self, int v):
if v != self.parent[v]:
self.parent[v] = self.find(self.parent[v])
return self.parent[v]
设置.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("cPercolation.pyx", annotate=True)
)
然后我在 Windows powershell 中运行 python setup.py build_ext --inplace 来编译代码。但是,当我导入代码并在 Python 中尝试时,有时会出现错误(进程不返回 0),有时会在我调用 find 方法时出现 RecursionError。那么翻译上述代码的正确方法是什么?我已经阅读了官方文档,但对于cdef、cpdef之类的内容,我仍然不确定。
编辑:我已经添加了 for 循环来解决问题,但我应该如何改进 cython 代码?当我查看生成的 html 文件时,仍然有很多黄色高亮显示(python 交互)。具体来说,我想问一下我应该如何使用 cdef、cpdef 使类方法 (DisjointSet.find) 更像 C++ 代码。
请您参考如下方法:
C++ vector 运算符[] does not check bounds ,越界访问给出了一个随机值,这会导致后续向量访问中出现段错误,您会注意到一个非零退出代码。
相反,使用.at(),which has bounds checking ,cython会将std::out_of_range异常翻译成IndexError:
def find(self, int v):
try:
pv = self.parent.at(v)
except IndexError:
return None
...
