函数调用后Python数组值意外更改
我有一个小函数,它使用一个列表填充另一个列表。由于某种原因,源列表会被修改。我没有一行操作源代码列表函数调用后Python数组值意外更改,python,scope,Python,Scope,我有一个小函数,它使用一个列表填充另一个列表。由于某种原因,源列表会被修改。我没有一行操作源代码列表arr。我可能缺少Python处理变量范围、列表的方式。我的预期输出是在函数调用后列表arr保持不变 numTestRows = 5 m = 2 def getTestData(): data['test'] = [] size_c = len(arr) for i in range(numTestRows): data['test'].append(arr
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']]
您错误地处理了列表列表(不是
矩阵
)中的引用。也许如果我们再细分一下,你就能看到发生了什么。以两个字符列表作为独立变量启动主程序:
left = ['a', 'b', 'c', 'd', 'e']
right = ['f', 'g', 'h', 'i', 'j']
arr = [left, right]
现在,看看您的函数在关键行中发生了什么。在第一次迭代中,大小c是2,i是0
data['test'].append(arr[i%size_c])
这将把arr[0]
附加到数据[
测试]
,该数据以空列表开始。现在来看关键部分:arr[0]
不是一个新列表;相反,它是对我们现在在主程序中称为left
的列表的引用。这份名单只有一份
现在,当我们进入下一个循环时,我们点击以下语句:
data['test'][i].append('xyz')
data['test'][i]
是对与left
相同列表的引用。。。这就解释了在原始列表中添加的原因
您可以轻松复制后缀为[:]
的列表,在整个列表中创建一个新的片段。例如:
data['test'].append(arr[i%size_c][:])
。。。这应该可以解决您的引用问题。最好将变量(
data
和arr
)作为参数传递给getTestData()
为什么?我知道这被认为是一种很好的做法,但是当我需要跨函数使用变量时,全局变量比传递给每个函数要好。在我看来,data['test'].append(arr[I%size\u c])
将引用附加到数组的元素和data['test'][I].append('xyz'))
将数据存储到此对象。若要解决此问题,请更改行数据['test'].append(arr[i%size\u c])
到数据['test']。append(arr[i%size\u c][:])
以在将数组附加到字典而不是添加对它的引用时创建数组的新副本。是关于按值而不是按引用进行复制。您还可以使用copy()
,这比列表更通用。