python函数中把列表(list)当参数时的"入坑"与"出坑"

简介: 在Python函数中,传递的参数如果默认有一个为 列表(list),那么就要注意了,此处有坑.入坑挖坑def f(x,li=[]): for i in range(x): li.

在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)
    # Python学习交流QQ群:857662006  
 
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)
 
# Python学习交流QQ群:857662006
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:
        # Python学习交流QQ群:857662006
        # 如果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]
相关文章
|
29天前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
129 67
|
6天前
|
索引 Python
Python列表
Python列表。
33 8
|
9天前
|
C语言 Python
[oeasy]python054_python有哪些关键字_keyword_list_列表_reserved_words
本文介绍了Python的关键字列表及其使用规则。通过回顾`hello world`示例,解释了Python中的标识符命名规则,并探讨了关键字如`if`、`for`、`in`等不能作为变量名的原因。最后,通过`import keyword`和`print(keyword.kwlist)`展示了Python的所有关键字,并总结了关键字不能用作标识符的规则。
25 9
|
17天前
|
数据挖掘 大数据 数据处理
python--列表list切分(超详细)
通过这些思维导图和分析说明表,您可以更直观地理解Python列表切分的概念、用法和实际应用。希望本文能帮助您更高效地使用Python进行数据处理和分析。
33 14
|
23天前
|
Python
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
47 18
|
14天前
|
数据可视化 DataX Python
Seaborn 教程-绘图函数
Seaborn 教程-绘图函数
43 8
|
19天前
|
数据挖掘 大数据 数据处理
python--列表list切分(超详细)
通过这些思维导图和分析说明表,您可以更直观地理解Python列表切分的概念、用法和实际应用。希望本文能帮助您更高效地使用Python进行数据处理和分析。
31 10
|
24天前
|
Python
Python中的函数
Python中的函数
37 8
|
1月前
|
监控 测试技术 数据库
Python中的装饰器:解锁函数增强的魔法####
本文深入探讨了Python语言中一个既强大又灵活的特性——装饰器(Decorator),它以一种优雅的方式实现了函数功能的扩展与增强。不同于传统的代码复用机制,装饰器通过高阶函数的形式,为开发者提供了在不修改原函数源代码的前提下,动态添加新功能的能力。我们将从装饰器的基本概念入手,逐步解析其工作原理,并通过一系列实例展示如何利用装饰器进行日志记录、性能测试、事务处理等常见任务,最终揭示装饰器在提升代码可读性、维护性和功能性方面的独特价值。 ####
|
6月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
1046 1