Cython,有办法创建只有一种类型的列表吗?(与Python列表不同)
在我的 Group
类里,必须有一个属性 particles
,这个属性应该是一个像数组一样的类型,但要能调整大小,并且只能存放 Particle
实例。
这两个类,Group
和 Particle
,都是用 cdef
声明的。
因为 Python 的列表可以存放任何 Python 对象,我在想有没有更高效的方法来声明一种只接受 Particle
实例的 C 列表。在 C 语言中,这可能类似于 List<Particle> particle = new List<Particle>();
。
在 Cython 中有没有类似的东西,还是说我就应该继续使用 Python 列表呢?
4 个回答
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
我不确定这样做是否能提高性能,但如果你想确保列表里只包含特定类型的数据……
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中,常见的速度提升方法并不太管用。因为Python内部已经有很多缓存和优化,所以你通常不会通过用C语言的思维方式来获得太多提升——除非你是在写C语言模块。
1
这个问题值得思考:你为什么想要这样做呢?
- 是为了提高效率(比如遍历数组)还是为了减少内存占用?
- 你需要用数组,还是用链表就够了?
- 你的粒子类是简单的数据结构,还是有一些功能和方法的复杂对象?
根据这些不同的情况,最合适的解决方案可能是使用Python数组、Numpy库,或者STL容器。
(举个例子,在Cython中遍历Python列表可能会非常高效。)