在python中创建类似对象集合的最有效的方法/数据结构是什么?
示例:
假设我有许多Point()
个实例。每个实例都有x
属性。
我想将它们组合在一起以执行批量操作等。
我可能只是将它们全部放在一个列表中:
points = [Point(x=1), Point(4), Point(7)... Point(1)]
我可以创建一个简单地将此列表作为输入的类:
Class PointCollection():
def __init__(self, points):
""" points is a list of Point() instances """
self.points = points
为了访问所有x
属性,该类可能有一个如下所示的方法:
@property
def allX(self):
return [pnt.x for pnt in self.points]
我的问题是,有更好的方法吗?我可以想象,对于具有需要循环访问的属性的大量点的集合可能需要一些时间来计算。在更复杂的集合中,您可能拥有许多属性或更深层次的嵌套属性(集合集合?)。
是否有更好的数据结构可供实施?或者最好转向Cython和/或多处理以获得更高的性能?
编辑:
以下是关于我具体问题的更多细节:
这涉及一些GIS数据结构 - 即描述河流支流的类。这些集合将描述一个河流网络,我正在寻找访问整个网络执行批量操作的类似属性(如每个支流的x坐标,或'链接')。
但是,我想要创建一个非常通用的“集合”结构的“最佳”方法,这就是我使用Point()
示例的原因。我可以看到这在我工作的其他方面很有用......
答案 0 :(得分:3)
如果您主要处理数字数据,请考虑使用NumPy及其recarray
:
>>> import numpy
>>> a = numpy.array([(1.0, 2.0), (7.3, -1.0), (4.2, 3.7)],
dtype=[("x", float), ("y", float)])
>>> b = a.view(numpy.recarray)
>>> b.x
array([ 1. , 7.3, 4.2])
>>> b[0]
(1.0, 2.0)
NumPy为数组数据提供了相当高效的矢量化操作。
答案 1 :(得分:1)
这个答案不包括性能问题,但你可以用更一般的方式处理这样的集合:
Class PointCollection:
def __getattr__(self, name):
return [point.__getattr__(name) for point in self.points]
def __setattr__(self, name, values):
for (point, value) in zip(self.points, values):
point.__setattr__(name, value)
def __init__(self, points):
""" points is a list of Point() instances """
self.points = points
现在,您可以直接在容器上获取/设置任何属性,它会自动将此类请求“重定向”到包含的元素,从而使您的容器更加灵活,以防您想要添加/删除属性。