mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
448 字
1 分钟
妙妙 Python * 2
2026-08-15

从这个视频引入

先来看题!#

chall

第一题(原题)#

def add_list(item, lst=[]):
lst.append(item)
return lst
print(add_list(1), add_list(2))

输出是[1, 2] [1, 2]。因为lst是同一个。

第一题A:[1] [2]#

加3字符

def add_list(item, lst=[]):
lst.append(item)
return lst
print(add_list(1), add_list(2,[]))

目前能想到最短的,同理换一下顺序也行:

def add_list(item, lst=[]):
lst.append(item)
return lst
print(add_list(1,[]), add_list(2))

思路是创建新的空lst

第一题C:[1] [1, 2]#

第一个想到的需要加4字符:

def add_list(item, lst=[1]):
lst.append(item)
# print(add_list.__defaults__)
return lst
print(add_list(1,[]), add_list(2))

但是啊重新思考一下,[1] [1, 2],实际上和我分开print是一样的,而分开print实际上就是闭包,让这个lst复制一份,而不是共享引用(不知道这么理解对不对,有点像CoW的)。而最简单的让lst是真实的值的办法就是对他进行一些操作,但为了尽可能少改,操作结果不能改变。而python里非常通用的操作就是*

def add_list(item, lst=[]):
lst.append(item)
return lst*1
print(add_list(1), add_list(2))

因此,只需要加2字符。

第二题(原题)#

funcs = [lambda: i for i in range(3)]
print([f() for f in funcs])

输出是[2, 2, 2],这个真得慢慢想才能理解。lambda表达式相当于return了i,但是i是变量,会延迟绑定,所以f() return的都是同一个i的引用

第二题A:[0, 1, 2]#

这个和第一题C有点像,本质上是要进行一次copy,而不要存引用。加4字符。

funcs = [lambda i=i: i for i in range(3)]
print([f() for f in funcs])

没忍住看了眼评论区,[]改(),2字符的确实精妙,推导式变生成器了

funcs = (lambda: i for i in range(3))
print([f() for f in funcs])

第二题C:[0, 0, 0]#

这个是先做的,lambda表达式,把return改成固定的就行,所以修改1字符

funcs = [lambda: 0 for i in range(3)]
print([f() for f in funcs])

第二题A还是算我的4字符,那么就是3+2+4+1=10。不考虑黑魔法,理论极限应该就是3+2+2+1=8?不过考虑到特定版本的UAF,可能还真不好说..(https://github.com/python/cpython/issues/91153,https://github.com/Nambers/python-audit_hook_head_finder)

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

妙妙 Python * 2
https://blog.chaomixian.top/posts/python-lmao/
作者
炒米线
发布于
2026-08-15
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录