函数调用后,Python数组值意外更改

问题描述 投票:1回答:1

我有一个小函数,它使用一个列表来填充另一个列表。由于某种原因,源列表被修改。我没有一行操纵源列表arr。我可能错过了Python处理变量范围列表的方式。我的预期输出是在函数调用后列表arr保持不变。

numTestRows = 5
m = 2
def getTestData():
    data['test'] = []
    size_c = len(arr)
    for i in range(numTestRows):
        data['test'].append(arr[i%size_c])
        for j in range(m):
            data['test'][i].append('xyz')

#just a 2x5 str matrix
arr = [['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h', 'i', 'j']]
print('Array before: ')
print( arr)
data = {}
getTestData()
print('Array after: ')
print( arr)

产量

Array before: 
[['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h', 'i', 'j']]
Array after: 
[['a', 'b', 'c', 'd', 'e', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'], ['f', 'g', 'h', 'i', 'j', 'xyz', 'xyz', 'xyz', 'xyz']]
python scope
1个回答
2
投票

你错误地处理了列表列表中的引用(而不是matrix)。也许如果我们再打破一点,你可以看到发生了什么。使用两个char列表作为单独的变量启动主程序:

left  = ['a', 'b', 'c', 'd', 'e']
right = ['f', 'g', 'h', 'i', 'j']
arr = [left, right]

现在,看看你的功能在关键线上发生了什么。在第一次迭代中,size_c为2,i为0 ...

    data['test'].append(arr[i%size_c])

这会将arr[0]附加到data[test],这是一个空列表。现在关键部分:arr[0]不是新的名单;相反,它是对我们现在在主程序中称为left的列表的引用。此列表只有一个副本。

现在,当我们进入下一个循环时,我们点击了声明:

        data['test'][i].append('xyz')

data['test'][i]是与left相同列表的引用...这解释了原始列表的附加内容。

您可以轻松地复制带有后缀[:]的列表,从而创建整个列表的新切片。例如:

data['test'].append(arr[i%size_c][:])

......这应该可以解决您的参考问题。

© www.soinside.com 2019 - 2024. All rights reserved.