作者:假装坚持-我很不爽_547 | 来源:互联网 | 2022-12-07 10:22
我在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]
setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("cPercolation.pyx", annotate=True)
)
我python setup.py build_ext --inplace
在Windows PowerShell中运行以编译代码.但是,当我导入代码并在Python中尝试它时,它有时会给出错误(进程不返回0),并且当我调用find方法时有时会给出RecursionError.那么翻译上述代码的正确方法是什么?我已阅读官方文档,我真不知道这样的事情cdef
,cpdef
.
编辑:我已添加for循环来解决问题,但仍然应该如何改进cython代码?当我看到生成的html文件时,仍然有很多黄色亮点(python交互).具体来说,我想问一下如何使用cdef
,cpdef
使类methods(DisjointSet.find
)更像C++代码.
1> georgexsh..:
C++ vector
运算符[]
不检查边界,越界访问给出随机值,这导致后续向量访问中的段错误,您会注意到非零退出代码.
相反,使用.at()
,有界限检查,cython将std::out_of_range
异常转换为IndexError
:
def find(self, int v):
try:
pv = self.parent.at(v)
except IndexError:
return None
...