在Python函数中,传递的参数如果默认有一个为 列表(list),那么就要注意了,此处有坑!!

入坑

def f(x,li=[]):
for i in range(x):
li.append(i*i)
print(li) print('---1---')
f(4)
print('---2---')
f(5)

预期结果

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]

执行结果

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 0, 1, 4, 9, 16]

出坑

当定义函数时,会保存函数中默认参数 list 的值,也就是列表 li=[];

在每次调用的时候如果传递了新的列表,则使用传递的列表,没有传递,使用定义函数时保存的默认参数(li=[]);

上面两次调用中,都没有传递新的列表(使用默认列表 li=[] ),程序会调用定义函数时保存的默认参数((li=[]));

列表在append的时候会在 li=[] 原来的基础上append追加值,所以会产生以上结果.

通过打印列表的ID进行辨识

打印列表 li=[] 的ID:

def f(x,li=[]):
print(id(li)) # 添加打印id
for i in range(x):
li.append(i*i)
print(li) print('---1---')
f(4)
print('---2---')
f(5)

结果:

---1---
140306123906248
[0, 1, 4, 9]
---2---
140306123906248
[0, 1, 4, 9, 0, 1, 4, 9, 16]

会发现ID值是相同的;

说明两次执行时使用的都是定义函数时的默认参数 li=[ ]

执行时往里面传新的列表

打印列表 li=[] 的ID 和 传的新列表的ID:

def f(x,li=[]):
print(id(li))
for i in range(x):
li.append(i*i)
print(li) print('---1---')
f(4)
print('---2---')
f(5,[])
print('---3---')
f(6)

结果:

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]
---3---
[0, 1, 4, 9, 0, 1, 4, 9, 16, 25]

会发现执行传递空(新)列表的函数时打印的ID不一样,而没有传递的一样;

当传递空列表时,函数体当中会使用传递的空列表,没有传递时,使用函数默认值 li=[ ], 所以会产生以上结果。

优化

如果想要达到预期的结果,只需要在函数体里进行判断即可:

def f(x, li=[]):
if not li:
# 如果li不为空的话,就往下走(清空列表); 为空就不走
li = []
for i in range(x):
li.append(i * i)
print(li) print('---1---')
f(4)
print('---2---')
f(5)
print('---3---')
f(6)

结果:

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]
---3---
[0, 1, 4, 9, 16, 25]

python函数中把列表(list)当参数时的"入坑"与"出坑"的更多相关文章

  1. Python之在函数中使用列表作为默认参数

      本文将介绍笔者在工作中遇到的Python的一个坑,那就是使用列表作为默认参数.   我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使 ...

  2. Python在函数中使用列表作为默认参数

    在学习中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使用列表作为函数的默认参 ...

  3. Python函数中的列表

    在看21天的Python书中写出了一个陷阱,但没给出解释,以下为代码陷阱

  4. python函数中的位置参数、默认参数、关键字参数、可变参数区别

    一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_d ...

  5. Python 函数中,参数是传值,还是传引用?

    在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...

  6. Python函数中参数类型

    在学习Python函数的时候,函数本身的定义和调用并不是很复杂,但是函数的参数类型和用法的确有些复杂.在此做一个小结,加深理解. Python参数的定义 负责给函数提供一些必要的数据或信息,以保证函数 ...

  7. Python函数中的可变参数

    在Python函数中,还可以定义可变参数. 如:给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……. 要定义出这个函数,我们必须确定输入的参数.由于参数个数不确定,我们首先想到可以把 ...

  8. python函数中的参数类型

    python函数中的参数 动态获取函数的参数 python的函数类型详解

  9. 一道题带你搞定Python函数中形参和实参问题

    昨天在Python学习群里有位路人甲问了个Python函数中关于形参和实参一个很基础的问题,虽然很基础,但是对于很多小白来说不一定简单,反而会被搞得稀里糊涂.人生苦短,我用Python. 为了解答大家 ...

随机推荐

  1. java获取http请求的Header和Body

    在http请求中,有Header和Body之分,读取header使用request.getHeader("..."); 读取Body使用request.getReader(),但g ...

  2. eclipse 开发web程序,启动tomcat插件服务器的时候。部署目录在那里?

    不在tomcat-home/webapps/下面, 你做一个文件上传功能看看就知道了,临时目录一般是你的工作区间workspace\.metadata\.plugins\org.eclipse.wst ...

  3. 常用的快速Web原型图设计工具

    做产品原型是非常重要的一个环节,做产品原型就会用使用各式各样的工具.在PM朋友们的推荐下使用了很多各种各样的软件,当然选择一款真正适合自己的工具也是很重要,在这里就把我使用过的工具都介绍一下. 主要有 ...

  4. python opencv 人脸识别

    def findface(image): import cv2  frame=cv2.imread('n1.jpg') classifier=cv2.CascadeClassifier("h ...

  5. 【BZOJ】【3675】【APIO2014】序列分割

    DP+斜率优化 首先我们根据这个分割的过程可以发现:总得分等于k+1段两两的乘积的和(乘法分配律),也就是说与分割顺序是无关的. 再对乘积进行重分组(还是乘法分配律)我们可以转化为:$ans=\sum ...

  6. 可操纵网页URL地址的js插件-url.js

    url.js是一款能够很有用方便的操纵网页URL地址的js插件.通过url.js你能够设置和获取当前URL的參数,也能够对当前URL的參数进行更新.删除操作.还能够将当前URL的參数显示为json字符 ...

  7. Qt Quick 和qml介绍

    很多人不了解Qt Quick和Qml,还有很多人对其存在偏见.这篇文章就是来向这些有困惑的人介绍一下其是什么,有什么特点. 首先,这两个是一个东西吗? 答案:是的.但是,具体来说,Qt Quick是框 ...

  8. 网页IE轻松调用VLC播放器实现监控(组件+方法大全)【转】

    公司突发奇想,要把刚买回来的网络监控机用自己内部网站在线监控. 作为网站的开发员,我接下了这个任务. 网络上有很多资料参与,但是都不全都不尽人意,最后经过多次的不同关键字的查找和测试,总算让我成功了. ...

  9. Python中filter、map、reduce、lambda 的用法

    Python内置了一些非常有趣但非常有用的函数,充分体现了Python的语言魅力! filter(function, sequence):对sequence中的item依次执行function(ite ...

  10. 让 IE6, 7和 8支持CSS3的HTC文件补丁

    让 IE6, 7和 8支持CSS3 IE6,7并不支持CSS3的属性,IE8也不能很好的支持CSS3.但是有一个小脚本能够做到,它可以让IE支持CSS3,包括:border-radius (round ...