修改reduce()返回值为何影响原字典?单/多键字典表现差异
问题原因解析
这是因为Python中列表是可变对象,再结合reduce函数的工作逻辑,才出现了两种截然不同的结果:
单键值对场景
当字典只有{'foo': [1,2,3]}这一组键值对时,d.values()返回的是仅包含一个列表的可迭代对象。reduce函数在未指定初始值的情况下,会直接把这个唯一的元素作为最终结果返回——也就是说all_vals其实是原字典中foo对应列表的引用,并非新创建的列表。
此时对all_vals执行append(4),本质就是在修改原字典里的那个列表,所以打印字典时会看到内容变化。
多键值对场景
当字典包含两组键值对时,d.values()返回包含两个列表的可迭代对象。reduce会按如下逻辑执行:
- 先取第一个列表
[1,2,3]作为初始值x,第二个列表[9]作为y - 执行
x + y,列表的+操作会创建一个全新的列表[1,2,3,9],并将这个新列表作为下一轮的x - 由于没有更多元素,最终
all_vals就是这个新创建的列表,和原字典里的两个列表没有引用关联
所以后续修改all_vals只会影响这个新列表,原字典中的列表不会被改动。
验证代码
你可以用is运算符直接判断是否为同一个对象:
from functools import reduce d1 = {'foo': [1,2,3]} all_vals1 = reduce(lambda x, y: x + y, d1.values()) print(all_vals1 is d1['foo']) # 输出 True,说明是同一个对象 d2 = {'foo': [1,2,3], 'bar': [9]} all_vals2 = reduce(lambda x, y: x + y, d2.values()) print(all_vals2 is d2['foo']) # 输出 False,说明是新对象 print(all_vals2 is d2['bar']) # 输出 False,和原字典里的列表都无关
内容的提问来源于stack exchange,提问作者mchristos
相关产品推荐
相关产品推荐

