Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数调用后Python数组值意外更改_Python_Scope - Fatal编程技术网

函数调用后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()
,这比列表更通用。