代码为何重复打印同一内容五次?如何修改实现打印五个不同名字?
问题原因
嘿,这个坑我当初刚学编程的时候也踩过!这本质是循环变量的作用域与延迟绑定导致的问题。举个典型的错误代码例子(应该和你写的逻辑类似):
names = ["Alice", "Bob", "Charlie", "David", "Eve"] print_funcs = [] for name in names: # 每个lambda都引用了同一个name变量 print_funcs.append(lambda: print(name)) # 调用所有函数时,循环已经结束,name固定为最后一个值 for func in print_funcs: func()
说白了,循环里的name是同一个变量——它在整个循环过程中只是被不断赋值新的名字,而不是每次循环都生成一个全新的变量。而lambda函数并没有“保存”当前循环的name值,只是保存了对这个变量的引用。当你后面调用这些函数时,循环早就跑完了,name已经变成列表的最后一个元素,所以所有函数都会打印它。
修复方法
给你三种常用的修复思路,按需选就行:
方法1:用默认参数捕获当前值
这是最简单的写法,利用lambda默认参数在定义时就求值的特性,把当前的name值绑定进去:names = ["Alice", "Bob", "Charlie", "David", "Eve"] print_funcs = [] for name in names: # 每次循环都会把当前name的值作为默认参数n保存 print_funcs.append(lambda n=name: print(n)) for func in print_funcs: func()方法2:用嵌套函数创建独立作用域
用一个内层函数来包裹,每次循环都会生成一个新的局部作用域,把当前name的值存进去:names = ["Alice", "Bob", "Charlie", "David", "Eve"] print_funcs = [] def create_printer(current_name): # 这里的current_name是每个循环独有的局部变量 return lambda: print(current_name) for name in names: print_funcs.append(create_printer(name)) for func in print_funcs: func()方法3:用functools.partial绑定参数
如果是调用现成的函数(比如这里的print),可以用partial直接把参数绑定好,生成新的可调用对象:from functools import partial names = ["Alice", "Bob", "Charlie", "David", "Eve"] print_funcs = [] for name in names: # 把当前name绑定为print的第一个参数 print_funcs.append(partial(print, name)) for func in print_funcs: func()
内容的提问来源于stack exchange,提问作者blackwater7
相关产品推荐
相关产品推荐

