为什么我的Python for循环remove()改变在循环之前声明的变量?

时间:2014-04-19 09:56:57

标签: python python-2.7

这是我的函数的简化版本,它比较了三组数字并找到了两组具有最高相关性:

inputs = ['vars_one', 'vars_two', 'vars_three']
def MostCorrelatedInputs(inputs):
    correlation = 0
    saved_inputs = inputs
    for i in inputs:
        testlist = saved_inputs
        testlist.remove(i)
        new_correlation = FindCorrelation(testlist)
        if new_correlation > correlation:
            correlation = new_correlation
            outputs = testlist
    return outputs

问题是,当我运行该函数时,似乎remove()函数改变了saved_inputs变量,即使我在inputs上调用它。这是垃圾收集的问题吗?为什么saved_inputs变量被我的for循环改变了,如果remove()预计会改变这个变量,是否有更好的方法来实现我的目标?

3 个答案:

答案 0 :(得分:3)

我会给你一个提示:

>>>a = [1,2,3]
>>>b = a
>>>b.remove(1)
>>>a
[2, 3]

这是因为b引用与a相同的对象!如果您从b中删除某些内容,则会将其从a引用的对象中删除。要更改此设置,请在创建副本时执行

>>>b = a[:]
>>>b.remove(1)
>>>a
[1, 2, 3]
>>>b
[2, 3]

答案 1 :(得分:1)

所以当你这样做时:

saved_inputs = inputs

testlist = saved_inputs

testlist和saved_inputs都引用相同的对象/列表 - 输入。

您需要获得类似列表的“深层副本”。 I-E

引用您的示例代码:

testlist = saved_inputs

testlist.remove('vars_one')

print testlist
print saved_inputs

这将导致:

['vars_two', 'vars_three']
['vars_two', 'vars_three']

你必须做这样的事情:

testlist = list(saved_inputs)

testlist.remove('vars_one')

print testlist
print saved_inputs

要获得结果:

['vars_two', 'vars_three']
['vars_one', 'vars_two', 'vars_three']

我认为这就是你所期待的。

答案 2 :(得分:0)

您要声明测试列表以引用与输入相同的引用。

因此,如果您想让testlist只包含值而不包含引用,则需要对列表执行以下操作:

inputlist = inputs[:]