python函数中把列表(list)当参数时的"入坑"与"出坑"
在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)当参数时的"入坑"与"出坑"的更多相关文章
- Python之在函数中使用列表作为默认参数
本文将介绍笔者在工作中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使 ...
- Python在函数中使用列表作为默认参数
在学习中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使用列表作为函数的默认参 ...
- Python函数中的列表
在看21天的Python书中写出了一个陷阱,但没给出解释,以下为代码陷阱
- python函数中的位置参数、默认参数、关键字参数、可变参数区别
一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_d ...
- Python 函数中,参数是传值,还是传引用?
在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...
- Python函数中参数类型
在学习Python函数的时候,函数本身的定义和调用并不是很复杂,但是函数的参数类型和用法的确有些复杂.在此做一个小结,加深理解. Python参数的定义 负责给函数提供一些必要的数据或信息,以保证函数 ...
- Python函数中的可变参数
在Python函数中,还可以定义可变参数. 如:给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……. 要定义出这个函数,我们必须确定输入的参数.由于参数个数不确定,我们首先想到可以把 ...
- python函数中的参数类型
python函数中的参数 动态获取函数的参数 python的函数类型详解
- 一道题带你搞定Python函数中形参和实参问题
昨天在Python学习群里有位路人甲问了个Python函数中关于形参和实参一个很基础的问题,虽然很基础,但是对于很多小白来说不一定简单,反而会被搞得稀里糊涂.人生苦短,我用Python. 为了解答大家 ...
随机推荐
- 优化JDBC编程-多提提意见
优化JDBC编程这是我根据MS SQL SERVER 2000 JDBC DRIVER HELP,并参考其它资料整理而成.ms的这个帮助文件实在有失大家风范,示例代码很.....有兴趣者可以去下载ht ...
- OpenShift上部署Redis主从集群
客户有部署有状态服务的需求,单机部署模式相对简单,尝试一下集群部署. 关于Redis的master,slave 以及sentinal的架构和作用不提,有兴趣可以参考之前的博客 https://www. ...
- C++ 竞赛常用头文件
C.传统 C++ #include <assert.h> 设定插入点 #include <ctype.h> 字符处理 #include <errno.h> 定义错误 ...
- OpenCV 脸部跟踪(1)
本文中的知识来自于Mastering opencv with practical computer vision project一书. 本文实施的脸部跟踪算法都是基于数据驱动的,主要 ...
- Jump Game II leetcode java
题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...
- 【Gson】简介 文档 基本使用 示例
简介 new TypeToken<List<Person>>() {}.getType() 1 1 1 new TypeToken<List<Person> ...
- POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新
题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...
- 廖雪峰的python学习网址
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00140737570055886 ...
- (转)[原创]在ios android设备上使用 Protobuf (使用源码方式)
自:http://game.ceeger.com/forum/read.php?tid=13479 如果你的工程只能以.Net 2.0而不能以.Net 2.0 subset运行,请看另外一个方法. 地 ...
- matlab中将矩阵按照行打乱顺序的一个例子
来自百度百科: A = [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12] rowrank = randperm(size(A, 1)); % 随机打乱的数字,从1~行数打 ...