Python中按引用传递的数据结构谨慎复制操作

函数中对参数没有进行全部复制

python测试代码

import numpy as np
import pandas as pd

def local(data):
    data.loc['a','a1']=100
    print('局部函数中变量修改后的结果')
    print(data)

def process():
    rows=['a','b','c']
    cols=['a1','b2','c3']
    data=pd.DataFrame(np.arange(9).reshape((3,3)),index=rows,columns=cols)
    print(data)
    local(data)
    print('局部函数中的变量只有局部的修改动作,修改后仍然是传入变量的引用')
    print(data)

if __name__=='__main__':
    process()

输出结果如下

    a1  b2  c3
a   0   1   2
b   3   4   5
c   6   7   8
局部函数中变量修改后的结果
    a1  b2  c3
a  100   1   2
b    3   4   5
c    6   7   8
局部函数中的变量只有局部的修改动作,修改后仍然是传入变量的引用
    a1  b2  c3
a  100   1   2
b    3   4   5
c    6   7   8

结论
类似于local函数中的那种只改变DataFrame中的局部数据,而不进行复制操作,类似于变量名[索引]=XXX 则DataFrame是按引用传递,在local函数中的任何修改都会在变量传入所在的函数中反应出来。

函数中对参数进行全部复制

Python代码如下:

import numpy as np
import pandas as pd

def copy(data):
    data=data.drop(['a1'],axis=1)
    print('局部函数中变量复制后的结果')
    print(data)

def process():
    rows=['a','b','c']
    cols=['a1','b2','c3']
    data=pd.DataFrame(np.arange(9).reshape((3,3)),index=rows,columns=cols)
    print(data)
    copy(data)
    print('局部函数中的变量重新复制了一份,复制后的变量不再是传入变量的引用')
    print(data)
if __name__=='__main__':
    process()

运行结果:

   a1  b2  c3
a   0   1   2
b   3   4   5
c   6   7   8
局部函数中变量复制后的结果
   b2  c3
a   1   2
b   4   5
c   7   8
局部函数中的变量重新复制了一份,复制后的变量不再是传入变量的引用
   a1  b2  c3
a   0   1   2
b   3   4   5
c   6   7   8

结论:
如果传入的DataFram变量在局部函数中存在类似于 变量名=XXX 的代码,则传入的变量产生的复制操作,复制后的变量不在是传入变量的引用。

总结

Python中大多数数据结构是按引用传递的,在传递过程中谨慎使用 变量名=XXX 这样的复制操作,这将导致按引用传递的目的无法达到。当然可以通过返回值的方式达到同样的目的。当然,类似于内置类型、元组、字符串等按值传递的数据结构不存在这个问题,要想获得修改后的结果必须使用返回值的方式。

你可能感兴趣的:(Python备忘录,python,函数,数据结构)