python函数传递列表_python函数的参数传递

1、准确地说,Python 的参数传递是赋值传递(pass by assignment),或者叫作对象的引用传递(pass by object reference)。Python 里所有的数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已,并不存在值传递或是引用传递一说。

def my_func(b):

b = 2

a =1

my_func(a)

print(a)

-----

1

这里的参数传递,使变量 a 和 b 同时指向了 1 这个对象。但当我们执行到 b = 2 时,系统会重新创建一个值为 2 的新对象,并让 b 指向它;而 a 仍然指向 1 这个对象。所以,a 的值不变,仍然为 1。

2、我们只需稍作改变,让函数返回新变量,赋给 a。这样,a 就指向了一个新的值为 2 的对象,a 的值也因此变为 2。

def my_func2(b):

b = 2

return b

a = 1

a = my_func2(a)

a

2

3、 不过,当可变对象当作参数传入函数里的时候,改变可变对象的值,就会影响所有指向它的变量。比如下面的例子:

def my_func3(l2):

l2.append(4)

l1 = [1, 2, 3]

my_func3(l1)

l1

[1, 2, 3, 4]

这里 l1 和 l2 先是同时指向值为 [1, 2, 3] 的列表。不过,由于列表可变,执行 append() 函数,对其末尾加入新元素 4 时,变量 l1 和 l2 的值也都随之改变了。

4、 但是,下面这个例子,看似都是给列表增加了一个新元素,却得到了明显不同的结果。

def my_func4(l2):

l2 = l2 + [4]

l1 = [1, 2, 3]

my_func4(l1)

l1

[1, 2, 3]

为什么 l1 仍然是 [1, 2, 3],而不是 [1, 2, 3, 4] 呢?

5、要注意,这里 l2 = l2 + [4],表示创建了一个“末尾加入元素 4“的新列表,并让 l2 指向这个新的对象。这个过程与 l1 无关,因此 l1 的值不变。当然,同样的,如果要改变 l1 的值,我们就得让上述函数返回一个新列表,再赋予 l1 即可:

def my_func5(l2):

l2 = l2 + [4]

return l2

l1 = [1, 2, 3]

l1 = my_func5(l1)

l1

[1, 2, 3, 4]

这里你尤其要记住的是,改变变量和重新赋值的区别:my_func3() 中单纯地改变了对象的值,因此函数返回后,所有指向该对象的变量都会被改变;

但 my_func4() 中则创建了新的对象,并赋值给一个本地变量,因此原变量仍然不变。

至于 my_func3() 和 my_func5() 的用法,两者虽然写法不同,但实现的功能一致。不过,在实际工作应用中,我们往往倾向于类似 my_func5() 的写法,添加返回语句。这样更简洁明了,不易出错。

总结:里的赋值或对象的引用传递,不是指向一个具体的内存地址,而是指向一个具体的对象。

如果对象是可变的,当其改变时,所有指向这个对象的变量都会改变。

如果对象不可变,简单的赋值只能改变其中一个变量的值,其余变量则不受影响。

如果你想通过一个函数来改变某个变量的值,通常有两种方法。一种是直接将可变数据类型(比如列表,字典,集合)当作参数传入,直接在其上修改;第二种则是创建一个新变量,来保存修改后的值,然后将其返回给原变量。在实际工作中,我们更倾向于使用后者,因为其表达清晰明了,不易出错。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值