如何创建含唯一lambda的defaultdict列表,解决循环赋值默认值覆盖问题
问题原因
这是Python闭包的晚绑定特性导致的:
闭包(你代码中使用的lambda)内部引用的变量不会在闭包定义阶段就存储变量的当前值,只会在闭包实际被调用执行时,才去查找变量的最新取值。
你在for循环中定义的所有lambda都共享同一个循环变量i,循环结束后i的值已经固定为len(original_dictlist)-1,后续所有defaultdict触发默认值逻辑调用lambda时,取到的i都是这个最终值,就会出现所有默认值被覆盖的现象。
解决方法
方法1:利用函数默认参数绑定即时值
Python函数的默认参数会在函数定义阶段就计算并存储值,我们可以给lambda添加一个默认参数传入当前循环的i值:
for i in range(len(original_dictlist)): lambda_dictlist.append(defaultdict(lambda i=i: default_values[i], original_dictlist[i]))
每次循环定义lambda时,当前的i值会作为默认参数被绑定存储,后续调用lambda时如果不传参,就会使用定义阶段绑定的i值,不会受后续循环变量变化的影响。
方法2:直接绑定默认值(更简洁)
如果不需要依赖索引取值,也可以直接在遍历的时候把默认值绑定到lambda的默认参数上,可读性更高:
for default_val, orig_dict in zip(default_values, original_dictlist): lambda_dictlist.append(defaultdict(lambda val=default_val: val, orig_dict))
内容的提问来源于stack exchange,提问作者Mara
相关产品推荐
相关产品推荐

