高效同时更新列表中的对象,可能涉及复制。怎么样?

时间:2013-09-22 05:56:53

标签: python copy deep-copy simultaneous

假设我有一个列表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)似乎有效。


问题是复制成为我的性能瓶颈,而深度复制需要与我的其余代码组合运行一样长。


我在SO和谷歌上寻找创意/解决方案,并集思广益,但似乎没有一个看好。

这个帖子的答案:https://stackoverflow.com/a/16711895/1858363,建议返回对象而不是修改它们。虽然这让我很困惑。返回修改后的对象有何帮助?

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


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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

说实话,我不知道你在做什么。但你有没有尝试向后迭代?这是一种强大的技术。

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

这将允许您更新而不会弄乱东西。您还可以使用向后迭代来从列表中删除元素。基本上任何依赖于序列的先前元素保持稳定的操作都可以通过向后迭代来完成。

如果您想另外执行g[0] = g[0] + g[len(g)-1],请将上面代码中的“0”更改为“-1”。它将告诉循环更进一步。