Cython,有办法创建只有一种类型的列表吗?(与Python列表不同)

3 投票
4 回答
4645 浏览
提问于 2025-04-16 23:12

在我的 Group 类里,必须有一个属性 particles,这个属性应该是一个像数组一样的类型,但要能调整大小,并且只能存放 Particle 实例。
这两个类,GroupParticle,都是用 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列表可能会非常高效。)

撰写回答