3

我正在尝试将 C 应用程序移植到 Python,并且有很多指针。这些是否相等:

obj->position = (float*) malloc(obj->totalItems * obj->xyz * sizeof (float));
for (i = 0; i < components; i++) {
    obj->comps[i].position = obj->position + obj->pOffset; // Pointer arithmetic
obj->pOffset += obj->comps[i].items * obj->xyz;
}

for i in range(self.totalItems * self.xyz):
    self.position.append(0.0)
for i in range(self.components):
    self.comps[i].position = self.position[self.pOffset:] # Position was a C pointer
    self.pOffset += self.comps[i].items * self.xyz

我知道 Python 对象是通过引用传递的,所以我想知道是否:

self.comps[N].position = [1,2,3,4]

将改变某些部分:

self.position[]
4

2 回答 2

3

也许是这样的:

self.position = [0.0 for _ in self.total_items * self.xyz]
for i in range(self.components):
    self.comps[i].position = self.p_offset
    self.p_offset += self.comps[i].items

在 Python 中,您可以更改类实例变量中的值。这称为“变异”实例。如果该类不允许这样做,则它是一个“不可变”类;如果它确实允许这样做,它就是一个“可变”类。字符串是不可变的,整数也是如此,但列表是可变的。

在 Python 中,我无法想到获取对列表中间部分的引用。列表是可变的:可以插入、删除等。那么引用应该做什么呢?

因此,与其进行指针数学运算并存储对列表中某个点的引用,不如只存储偏移量,然后在需要引用列表中的该点时使用偏移量来索引列表。

对于您的具体问题:

self.comps[N].position = [1,2,3,4]

这会将对象position内的名称重新绑定self.comps[N]到现在指向具有该值的新创建的列表实例,[1, 2, 3, 4]并且根本不会影响self.position。但是,如果您只是设置self.comps[i].position为索引值,则可以使用以下代码:

i = self.comps[N].position
lst = [1, 2, 3, 4]
self.position[i:i+len(lst)] = lst

这将在self.position列表中使用“切片”来替换值。

请注意,如果您使用 SciPy 甚至只是 NumPy,您可以定义一个numpy.array不是动态的;您可以使用“视图”来获取对列表一部分的引用。您可能想研究一下,尤其是在使用非常大的数组或矩阵时。

查看一个numpy数组?

于 2012-08-02T20:56:50.717 回答
1

self.comps[N].position = [1,2,3,4]

将 self.comps[N].position 设置为一个新列表。如果还有其他对 self.comps[N].position 的旧列表的引用,它们将不会被更改。

例子

x=[1,2,3]
y=x
print y #[1, 2, 3]
x[1]=4
print y #[1, 4, 3]
x=[4,5,6]
print y #[1, 4, 3]
于 2012-08-02T21:27:31.940 回答