在我的Group
课程中,必须有一个属性particles
,该属性应该是类似但可调整大小的类型,可以仅保持Particle
- 实例
。
使用Group
声明Particle
和cdef
这两个类。
由于Python列表可以携带任何Python对象,我认为可能有一种更高效的方式来声明某种只接受Particle
- 实例的C列表。
在C中,我会想到List<Particle> particle = new List<Particle>();
。
Cython是否有任何等价物,或者我应该继续使用Python列表?
答案 0 :(得分:2)
我不确定你是否会获得任何表现,但如果你想确保该列表只包含某些类型的数据......
class Group(Object):
#...
def isParticle(self, p):
return hasattr(p, "anAttributeOnlyParticlesHave")
def getPartiles(self):
return filter(self.isParticle, self._Particles)
def setParticles(self, newParticles):
self._Particles = filter(self.isParticle, newParticles)
particles = property(getParticles, setParticles)
同样,这不是太快,但它是你问题的直接答案。
你可能会通过写一个C模块获得一些东西 - 我不确定。如果你真的需要表现,你使用的是错误的语言。
通常,使用Python,典型的速度噱头不起作用。有足够的缓存和优化正在进行,你通常不会通过思考C语言来获得很多 - 除非你正在编写C模块。
答案 1 :(得分:2)
是的,您只需使用cpp中的相同矢量类:
from libcpp.vector cimport vector
cdef class Item:
cdef int amount
cdef str description
def allocate():
cdef vector[Item] bunch_of_items
for i in xrange(100):
bunch_of_items.push_back(Item())
编译:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext = Extension(
"extension_name",
["module_name.pyx", ],
language="c++",
libraries=["stdc++"],
cmdclass = {'build_ext': build_ext}
)
setup(
name = "name",
cmdclass = {"build_ext": build_ext},
ext_modules = [ext]
)
请记住,除非将其转换为python列表,否则无法将此向量列表传递回python。
答案 2 :(得分:1)
问题有待提出:你为什么要这样?
根据这些,最好的解决方案是使用python数组到numpy或stl容器。
(注意,例如,在cython中循环遍历python列表可能非常有效。)
答案 3 :(得分:0)
您可以将链接列表写为cython结构。我已将val的类型设置为int
,但您可以将其设置为任何结构类型。
from cpython.mem cimport PyMem_Malloc
cdef struct link:
int val
link *next
cdef link * create_link(int v, link *prev_link):
cdef link *x = <link *>PyMem_Malloc(sizeof(link))
x.val = v
x.next = NULL
if prev_link is not NULL:
prev_link.next = x
return x
然后您可以创建一个指向动态分配的链接对象的指针。
cpdef many_links(int n):
cdef link * l = NULL
cdef link * f = NULL # keeps track of the first elem in the list
for i in range(n):
l = create_link(i, l)
if f == NULL:
f = l
# Write out the linked list to a python list
cdef list r = []
c = f
while c.next != NULL:
r.append(c.val)
c = c.next
r.append(c.val)
return r