Python在函数中使用列表作为默认参数
在学习中遇到的Python的一个坑,那就是使用列表作为默认参数。
我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变。另一个需要注意的是,使用列表作为函数的默认参数时,列表的内容变化情况。
首先,我们看以下的代码例子:
def add(x, lst=[]):
if x not in lst:
lst.append(x)
return lst
def main():
list1 = add(1)
print(list1)
list2 = add(2)
print(list2)
list3 = add(3, [11, 12, 13, 14])
print(list3)
list4 = add(4)
print(list4)
main()
你可能以为输出的结果会是:
[1]
[2]
[11, 12, 13, 14, 3]
[4]
但事实上,该程序输出的结果是:
[1]
[1, 2]
[11, 12, 13, 14, 3]
[1, 2, 4]
这是为什么呢?函数add的功能是当x不在列表中时,将x追加给列表lst。当函数第一次执行时,参数lst的默认值[]被创建。这个默认值只会被创建一次。add(1)将1加到lst。
当函数再次被调用时,lst是[1]而不是[],因为lst只被创建一次。当参数的lst为[11,12,13,14]时,lst就是[11,12,13,14]。list4调用函数时,使用默认参数,因此,现在默认参数lst为[1,2]。
为了更好地理解调用情况,可以在add函数中输出lst的id,如以下代码:
def add(x, lst=[]):
print(id(lst))
if x not in lst:
lst.append(x)
return lst
def main():
list1 = add(1)
print(list1)
list2 = add(2)
print(list2)
list3 = add(3, [11, 12, 13, 14])
print(list3)
list4 = add(4)
print(list4)
main()
输出结果如下:
4469603648
[1]
4469603648
[1, 2]
4469670472
[11, 12, 13, 14, 3]
4469603648
[1, 2, 4]
可以看到,list1, list2, list4调用时默认参数的id并没有发生改变,而list3的id发生了改变。
这是Python使用列表作为默认参数的一个坑。那么,如何避免踩坑呢?如果想要使用默认列表在每次函数调用时都是[],可以像下面的程序那样修改函数参数:
def add(x, lst=None):
if lst is None:
lst = []
if x not in lst:
lst.append(x)
return lst
def main():
list1 = add(1)
print(list1)
list2 = add(2)
print(list2)
list3 = add(3, [11, 12, 13, 14])
print(list3)
list4 = add(4)
print(list4)
main()
输出的结果如下:
[1]
[2]
[11, 12, 13, 14, 3]
[4]
Python在函数中使用列表作为默认参数的更多相关文章
- Python之在函数中使用列表作为默认参数
本文将介绍笔者在工作中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使 ...
- python函数中把列表(list)当参数时的"入坑"与"出坑"
在Python函数中,传递的参数如果默认有一个为 列表(list),那么就要注意了,此处有坑!! 入坑 def f(x,li=[]): for i in range(x): li.append(i*i ...
- python函数中的位置参数、默认参数、关键字参数、可变参数区别
一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_d ...
- js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快、简单 post:安全,量大,不缓存)(服务器同步和异步区别:同步:等待服务器响应当中浏览器不能做别的事情)(ajax和jquery一起用的)
js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快.简单 post:安全,量大,不缓存)( ...
- python eval函数,将列表样式的字符串转化为列表
python eval函数,将列表样式的字符串转化为列表 >>> str_1 = '[1,2,3,4,5,6]'>>> type(str_1)<type 's ...
- Python函数中的列表
在看21天的Python书中写出了一个陷阱,但没给出解释,以下为代码陷阱
- Python虚拟机函数机制之位置参数的默认值(五)
位置参数的默认值 在Python中,允许函数的参数有默认值.假如函数f的参数value的默认值是1,在我们调用函数时,如果传递了value参数,那么f调用时value的值即为我们传递的值,如果调用时没 ...
- python中使用list作为默认参数且调用时不给其赋值的问题
最近在写代码时发现一个有趣的地方,当python中的函数使用list作为默认参数且调用时不给其赋值时,无法通过在函数中将其赋值为[]来达到清空此默认参数的目的.按照道理来说,函数f1中的list为局部 ...
- 多测师讲解python _函数中参数__高级讲师肖sir
函数中讲解参数: 形参和实参的认识 函数无参数的调用 函数单个参数的调用 函数多个参数的调用 # #调试函数给默认参数传新值,则函数使用新值 # 注意:当多种参数同时出现在函数中,默认参数要放在最后的 ...
随机推荐
- AcWing 158. 项链 (最小表示法)
项链 题源:https://www.acwing.com/problem/content/160/ 题目 原理:最小表示法 找字典序最小的字符串 循环移位,破环成链 (把原串复制一倍) memcpy ...
- 谈谈ThreadLocal的应用场景和注意事项?
特点 ThreadLocal和Sychronized都用于解决多线程间的并发访问,但它们实现的本质方法不同:sychronized利用锁使同一个代码块或变量在某时刻只能被一个线程访问,而ThreadL ...
- mybatis混淆概念
1.resultMap与resultType <mapper namespace="com.dao.FilmMapper"> <resultMap id=&quo ...
- Docker Compose 的介绍、安装与使用
什么是 Docker Compose? Compose 是 Docker 官方的开源项目,负责实现Docker容器集群的快速编排,开源代码在 https://github.com/docker/com ...
- java.time包 时间处理类
已经习惯用 Date类这里就不再赘述,下面介绍新的时间处理类 1.LocalDate类 // 本地日期LocalDate localDate = LocalDate.of(2022, 2, 27);S ...
- 命令工具 -(1)Vim 文本编辑器学习
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 提起 Linux,大家都听说过这句话:Linux 一切皆文件. 配置一个服务就是在修改它 ...
- muduo源码分析之回调模块
这次我们主要来说说muduo库中大量使用的回调机制.muduo主要使用的是利用Callback的方式来实现回调,首先我们在自己的EchoServer构造函数中有这样几行代码 EchoServer(Ev ...
- 推荐一款数据mock框架,无需任何依赖,贼牛逼
fox-mock 是基于Java Agent实现的自测,联调Mock利器.能解决你的这些问题: 开发过程中,依赖了下游多个接口,想跑个单测都必须得等下游把服务部署好 联调过程中,下游某个接口出问题,阻 ...
- django的下载安装,目录结构的介绍,简单的django应用
1.django的下载安装 pip3 install django==1.11.9 2.django的创建 1.在windows的cmd窗口下 1.1创建django项目 django-admin s ...
- Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1
必读: Android 12(S) 图像显示系统 - 开篇 一.前言 SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengi ...