python list 函数参数_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之在函数中使用列表作为默认参数

本文将介绍笔者在工作中遇到的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. 为了解答大家 ...

python 函数中使用全局变量

python 函数中如果需要使用全局变量,需要使用 global + 变量名 进行声明, 如果不声明,那么就是重新定义一个局部变量,并不会改变全局变量的值 n [1]: a = 3 In [2]: d ...

随机推荐

Sublime Text 3编译Sass - Sublime Text安装Sass插件

1.首先要安装sass,安装流程: http://www.w3cplus.com/sassguide/install.html 2.sublime text安装Package Control(已经安装 ...

User mode and kernel mode

[User mode and kernel mode] 参考:https://msdn.microsoft.com/en-us/library/windows/hardware/ff554836(v= ...

Python 删除目录中特定文件

代码如下,使用了递归: import sys currDir = sys.path[] import os def removeFile(dir,postfix): if os.path.isdir( ...

js文件内部导入引用js文件方法

function include(path){      var a=document.createElement("script");     a.type = "te ...

为什么 API 监控对于任何业务来说都重要?

对于商务运算来说一个比较稳定的趋势在于对 API 日渐增长的依赖性,几乎每一个代码级交互过程都会调用 API 来收集数据或触发某些关键过程.没有 API ,你将无法与同伴进行文件交流,没有 API , ...

继承Thread类和实现Runnable接口

一.采用继承Thread类方法的特点: 优势:编写简单,如果需要访问当前的线程,只需要使用this,并可以在run()方法中调用其他线程的方法: 劣势:线程已经继承了Thread类,不能继承其他的父类 ...

elk-filebeat-(效果图示)(四)

一.vim filebeat-6.3.2-linux-x86_64/filebeat.yml - type: log # Change to true to enable this input con ...

JAVA记录-SpringMVC集成redis

1.redis.properties #主机地址 redis.host=127.0.0.1 #端口号 redis.port=6379 #当池内没有返回对象时,最大等待时间毫秒数 redis.pool. ...

java字符串分解 StringTokenizer用法

Java中substring方法可以分解字符串,返回的是原字符串的一个子字符串.如果要讲一个字符串分解为一个一个的单词或者标记,StringTokenizer可以帮你. 先看个例子: 1 public ...

长大Tips

队名:CW 队员: B20150304403 王香辉 B20150304408 李孟君 B20150304411 曾翡 B20150304414 吴海波 B20150304430 文淼 B201503 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值