Python字典值追加至列表异常:重复最后元素问题排查
问题:API结果处理后列表元素重复显示最后一项
我正在处理API返回的结果字符串,目标是将这些值转换为元素为字典的列表。API返回的字符串格式如下:
result_str = '[{"abc.xyz": "80983098429842","dev.uvw": 898420920},' '{"abc.xyz": "80983098429843","dev.uvw": 898420921},' '{"abc.xyz": "80983098429844","dev.uvw": 898420922}]'
但运行代码后,列表里只重复出现最后一个元素,而非每个元素各出现一次。我的代码如下:
import json def format_api_value(result_str, split_char, label_map): results = json.loads(result_str) d = dict() output = [] for item in results: output.append(d) print(f"clearing d after appending {d} \n") d.clear() for k, v in item.items(): if split_char in k: key = k.split(split_char)[len(k.split(split_char))-1] if key in label_map: key = label_map[key] d[key] = v else: d[k] = v print(f"printing output intermediate {output}") print(f"returning final list output") print(output) return d if __name__ == "__main__": result_str = '[' \ '{"abc.xyz": "80983098429842","dev.uvw": 898420920},' \ '{"abc.xyz": "80983098429843","dev.uvw": 898420921},' \ '{"abc.xyz": "80983098429844","dev.uvw": 898420922}]' split_char = "." label_map = {"xyz": "xyz_1", "uvw": "uvw_1"} format_api_value(result_str, split_char, label_map)
预期输出:
[{'xyz_1': '80983098429842', 'uvw_1': 898420920}, {'xyz_1': '80983098429843', 'uvw_1': 898420921}, {'xyz_1': '80983098429844', 'uvw_1': 898420922}]
当前输出:
[{'xyz_1': '80983098429844', 'uvw_1': 898420922}, {'xyz_1': '80983098429844', 'uvw_1': 898420922}, {'xyz_1': '80983098429844', 'uvw_1': 898420922}]
问题原因
代码中复用了同一个字典对象d,列表output里添加的都是这个字典的引用。每次调用d.clear()后修改内容,所有引用指向的都是同一个内存地址的字典,最终所有元素都会显示最后一次修改后的结果。
修复方案
每次循环时创建新的字典实例,调整添加到列表的时机,同时修正返回值。修改后的代码如下:
import json def format_api_value(result_str, split_char, label_map): results = json.loads(result_str) output = [] for item in results: d = dict() # 每次循环生成新字典 for k, v in item.items(): if split_char in k: # 用[-1]直接取分割后的最后一段,写法更简洁 key = k.split(split_char)[-1] if key in label_map: key = label_map[key] d[key] = v else: d[k] = v output.append(d) # 处理完当前item再加入列表 print(f"printing output intermediate {output}") print(f"returning final list output") print(output) return output # 返回最终的列表而非单个字典 if __name__ == "__main__": result_str = '[' \ '{"abc.xyz": "80983098429842","dev.uvw": 898420920},' \ '{"abc.xyz": "80983098429843","dev.uvw": 898420921},' \ '{"abc.xyz": "80983098429844","dev.uvw": 898420922}]' split_char = "." label_map = {"xyz": "xyz_1", "uvw": "uvw_1"} format_api_value(result_str, split_char, label_map)
关键修改点
- 把字典
d的定义移到循环内部,每次迭代创建全新的字典对象 - 调整
output.append(d)的位置,确保当前item的键值对处理完成后再添加到列表 - 修正返回值,应该返回整理好的
output列表而不是单个字典d - 简化键的提取逻辑,
k.split(split_char)[-1]比原写法更直观高效
内容的提问来源于stack exchange,提问作者palamuGuy
相关产品推荐
相关产品推荐

