zoukankan      html  css  js  c++  java
  • python函数参数改变问题

    python函数参数改不改变的问题

    前几天在做项目的过程中发现了一个问题,向函数中传入一个list,在函数体内将其赋值给list,对list1操作后发现list也发生了变化,啊 ! 出乎意料。查了一下原因,原来python里有可变对象和不可变对象之分。只有传入的是不可变对象时,值才不发生改变,若是可变对象,充当函数参数时要注意了。

    不可变对象:Number ,String , Tuple,bool
    可变对象: List , Set , Dictionary是可以改变内部的元素

    下面总结一下:

    先看例子:

    def changestr (str):
        str = "inside"
        print "这是function中 , 值为:",str
    mystr = "outside"
    changestr(mystr)
    print "这是函数外边 , 值为:",mystr
    

    输出结果:

    这是function中 , 值为: inside
    这是函数外边 , 值为: outside
    

    即 传入不可变对象字符串,在函数内对其操作不影响调用结束后字符串的值,即不发生改变。

    ps: Number和Tuple结果是一样的,这三种类型只能通过重新赋值来改变对象的值 .

    def changestr (str):
        str.append(3)
        print "这是function中 , 值为:",str
    mystr = [1,2]
    changestr(mystr)
    print "这是函数外边 , 值为:",mystr
    

    结果:

    这是function中 , 值为: [1, 2, 3]
    这是函数外边 , 值为: [1, 2, 3]
    
    
    • 对于可变对象,在函数体中的修改 , 对对象本身的值发生了改变 , 在函数之外 , 该列表的内容依然发生了改变 , 这是事先就能猜测到的结果 , 因为python中的参数 , 传入的是变量引用的副本 , 它与变量指向同一个值.

    3

    
    def change2(list):
        list = [1,2,3,4]
    mylist = ["aa",21]
    print(mylist)
    change2(mylist)
    print(mylist)
    
    

    输出结果:

    
    ['aa', 21]
    ['aa', 21]
    

    可变对象在函数体中的重新赋值 , 没有对外部变量的值产生影响 , 不过仔细一想 , 却又在情理之中 .

    • 即变量中存储的是引用 , 是指向真正内容的内存地址(当然 ,java中的八大基本数据类型 , 变量名和值都是存储在堆栈中的 ) , 对变量重新赋值 , 相当于修改了变量副本存储的内存地址 , 而这时的变量已经和函数体外的变量不是同一个了, 在函数体之外的变量 , 依旧存储的是原本的内存地址 , 其值自然没有发生改变 .

    3

    def change2(list):
        list1 =list
        list1.append(34)
    mylist = ["aa",21]
    print mylist
    change2(mylist)
    print mylist
    
    

    输出结果:

    
    ['aa', 21]
    ['aa', 21, 34]
    
    • 函数体传入的参数 , 为函数体外变量引用的副本 .
    • 在函数体中改变变量指向的堆中的值 , 对函数外变量有效.
    • 在函数体中改变变量的引用 , 对函数外变量无效

    要想不改变原list,用copy.deepcopy()

    
    import copy
    def change2(list):
        list1=copy.deepcopy(list)
        list1.append(34)
    mylist = ["aa",21]
    print mylist
    change2(mylist)
    print mylist
    
    

    结果:

    ['aa', 21]
    ['aa', 21]
    
    

    要想改变bool型,将其作为返回值

    1. flag不做返回值,函数外不发生改变
    flag=True
    def change2(list,flag):
        list.append(34)
        flag=False
    
    mylist = ["aa",21]
    print mylist
    change2(mylist,flag)
    print mylist,flag
    
    

    结果:

    ['aa', 21]
    ['aa', 21, 34] True
    
    
    1. flag作为返回值,返回值可用,但函数仍然不发生改变
    flag=True
    def change2(list,flag):
        list.append(34)
        flag=False
        return flag
    
    mylist = ["aa",21]
    print mylist
    print change2(mylist,flag)
    print mylist,flag
    

    输出结果:

    ['aa', 21]
    False
    ['aa', 21, 34] True
    
  • 相关阅读:
    洛谷 P1886 滑动窗口 (单调队列)
    Acwing 288.休息时间 (环形DP)
    Acwing 287.积蓄程度 (树形DP换根)
    2020 Multi-University Training Contest 5 Tree (树形DP)
    剑指offer-JZ50-数组中的重复数字(C++)
    假设以下有一个结构体存放的是学生的记录,每条记录包括:学号、姓名、成绩
    剑指offer-JZ48-不用加减乘除做加法(C++)
    剑指offer-JZ51-构建乘积数组
    数据结构与算法->递归
    力扣(LeetCode)试题6-Z字形变换 C++代码
  • 原文地址:https://www.cnblogs.com/monkey-moon/p/9347505.html
Copyright © 2011-2022 走看看