0

假设我有一个列表 g(实际上是一个双重嵌套列表,它是三个维度,但为了清楚起见,这里将其简化为一维。)

g = [1,2,3,2,1]

我想要一个可以使 g[x] = g[x-1]+g[x] 的函数。不正确的方法是

def f(thing):
    for x in xrange(0,len(thing)):
        thing[x] += thing[x-1]
f(g)

这是错误的,因为它一个接一个地更新整数,而不是一次全部更新。另一种方法是复制 g。

gcopy = g[:]
def f(thing, copy):
    for x in xrange(0,len(thing)):
        thing[x] = copy[x]+copy[x-1]
g = gcopy[:]
f(g,gcopy)

如果 g 有对象,就像我的情况一样,copy.deepcopy(g)似乎可以工作。


问题是复制成为我的性能瓶颈,而 deepcopy 的运行时间与我其余代码的总和一样长。


我在 SO 和 Google 上搜索了一些想法/解决方案,并集思广益,但似乎都没有希望。

此线程的答案:https ://stackoverflow.com/a/16711895/1858363建议返回对象而不是修改它们。我对这意味着什么感到困惑。返回修改后的对象有什么帮助?

我听说使用 deepcopy 复制对象的计算成本很高。如果这是真的,一个可能的解决方案是用列表替换对象并将对象的属性存储为列表中的整数和浮点数。由于我有子类和继承,这会使所有内容几乎不可读,并且可能会变得更加混乱。由于只有列表,因此希望可以对每个列表、子列表、子子列表等进行浅拷贝,然后重新组合它们。可能不是一个好的解决方案,而且加速是否很大值得怀疑(尽管我还没有测试过)。


总而言之,有没有一种方法可以更有效地同时更改列表中每个对象的值,无论是否复制列表?还是我坚持使用 deepcopy?谢谢!

4

2 回答 2

1

To be honest I have no idea what you're doing. But have you tried backwards iteration? It's a powerful technique.

def f(thing):
    for x in xrange(len(thing) -1, 0, -1):
        thing[x] += thing[x-1]
f(g)

This will allow you to update without messing stuff up. You can also use backwards iteration to delete elements from a list. Essentially any operation which relies only on previous elements of a sequence remaining stable can be done through backwards iteration.

If you want to additionally do g[0] = g[0] + g[len(g)-1] then change the '0' in the code above to a '-1'. It will tell the loop to go one step further.

于 2013-09-22T06:04:44.220 回答
1

一般来说,我认为您不会找到一种快速的方法来使用这种数据依赖性进行就地列表编辑。如果您只依赖较早的项目,则向后迭代将起作用。如果您只有前向依赖项,前向迭代将起作用。如果两者都有,您将需要临时变量来存储原始值,直到不再需要它们为止。尤其是对于多维列表,这最终可能比仅复制列表效率低。

你可以使用 numpy 数组来做你想做的事吗?Numpy 擅长这种操作,虽然它最终会复制,但复制 numpy 数组比对嵌套列表执行 deepcopy() 快得多。

于 2013-09-22T06:11:58.433 回答