1、传递默认参数尽量使用不可变对象
为什么默认参数最好为不可变对象?
请看下面的例子:
def demo(item, item_list=[]):
item_list.append(item)
print(item_list)
demo('iphone') # ['iphone']
demo('xiaomi', item_list=['oppo','vivo']) # ['oppo', 'vivo', 'xiaomi']
demo('huawei') # ['iphone', 'huawei']
可以看到第三次传入“huawei”时,输出的列表中还存在第一次传入的“iphone”
原因: python中的def在每次执行时,都会初始化一个函数对象。由于 Python 中的函数参数传递的是对象,也可以认为是传地址
,在第一次初始化 def 的时候,如果参数默认值为可变对象,则会先生成这个可变对象的内存地址,然后这个默认参数 item_list 会与这个内存地址绑定(也就是说该函数用的是可变对象的内存地址)。
在后面的函数调用中,如果调用方指定了新的默认值,就会将原来的默认值覆盖。如果调用方没有指定新的默认值,那就会使用原来的默认值
具体过程:
第一次调用时:执行初始化,并生成[]的内存地址:28932523478(假设是这个)并与函数绑定
第二次调用时:因为指定了新的默认对象,地址为29932523478,并以 ”压栈” 的形式,将旧的可变对象地址进行替代并与函数绑定。然后当这次调用完成后,会将这个栈弹出。这时旧的可变对象地址再一次与函数绑定
第三次调用:继续使用旧的可变对象地址
解决思路:
def demo(item, item_list=[]):
if item_list != []:
item_list = []
item_list.append(item)
else:
item_list.append(item)
2、生成列表
a = [[]] *10
print(a) # [[], [], [], [], [], [], [], [], [], []]
这种写法看起来似乎没有问题。
但是:
a = [[]] *10
a[0].append(10)
print(a) # [[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]
print(id(a[0])) # 8650264
print(id(a[1])) # 8650264
原因还是因为列表时可变对象,* 10这种写法,后面9的个[]用的都是第一个[]的地址。
解决思路:
可以用列表推导式解决
a = [[] for i in range(10)]
print(a)
a[0].append(10)
a[1].append(20)
print(a)
3、去除列表中的元素
以去除能被3整除元素为例
lst = [1,2,3,4,5,6]
def remove(lst):
for item in lst:
if item % 3 == 0:
lst.remove(item)
return lst
res = remove(lst)
print(res) # [1, 2, 4, 5]
看上去似乎也没问题。
但如果移动一下列表中元素的位置,比如下面这样
lst = [1,2,3,6,4,5]
def remove(lst):
for item in lst:
if item % 3 == 0:
lst.remove(item)
return lst
res = remove(lst)
print(res) # [1, 2, 6, 4, 5]
原因:进行列表删除时,如果有2个符合条件的成员相挨着,只要用到了循环操作,删除第一个之后,第二个会自动补到第一个的位置上,导致第二个始终无法删除。
解决思路:可以根据索引现将符合成员进行替换为某一元素(不删除),然后统一删除
4、lambda
如果需要用lambda生成多个结果,带参数与不带参数有很大区别。
不带参数:
li = [lambda :x for x in range(10)]
for item in li:
print(item())
# 输出的全是9
带参数:
li = [lambda x:x for x in range(10)]
for item in li:
index = li.index(item)
print(item(index))
# 输出为1,2,3....9
原因:lambda表达式不会形成对函数体内变量的记忆,只记录最后一个状态。
可以在lambda的入参中带上参数x, 则可以返回每一次的表达式结果。
(如果对lambda不太了解的同学,可以看我之前的一篇)
如果对你有帮助,可否在文章右侧点个赞再走呢~~
本文为原创,转载请注明出处
python 如何避免大量的if else