循环追加JSON对象时值被最后读取值覆盖,列表转换异常求助
问题分析与解决:Python字典引用导致的重复值问题
需求说明
需要将以下嵌套列表结构:
[ [ { 'loadBalancer' : 'LBValue'}, { 'targetgrp' : ['tg1', 'tg2','tg3']} ] ]
转换为每个对象包含相同loadBalancer值和不同targetgrp值的列表:
[ {'loadBalancer' : 'LBValue', 'targetgrp' : 'tg1' }, {'loadBalancer' : 'LBValue', 'targetgrp' : 'tg2' }, {'loadBalancer' : 'LBValue', 'targetgrp' : 'tg3' }, ]
原代码及问题输出
你编写的Python代码:
albtglist = [[ { 'loadBalancer' : 'LBValue'}, { 'targetgrp' : ['tg1', 'tg2','tg3']} ]] finalformattedData = [] data = {} for x in albtglist: for x2 in x: if 'loadBalancer' in x2: data['albarn'] = x2['loadbalancer'] if 'targetgrp' in x2: for tg in x2: data['tgarn'] = tg arndata.append(finalformattedData) print(finalformattedData)
运行输出结果(所有targetgrp值被覆盖为最后一个):
[ {'loadbalancer' : 'LBValue', 'targetgrp' : 'tg3'}, {'loadbalancer' : 'LBValue', 'targetgrp' : 'tg3'} , {'loadbalancer' : 'LBValue', 'targetgrp' : 'tg3'} ]
问题原因
字典引用传递是核心问题:
你在循环外仅创建了一个data字典对象,每次循环修改的都是同一个字典的内容,然后将这个字典的引用添加到列表中。列表存储的不是字典的副本,而是指向同一字典的指针,最终所有列表元素都会指向最后一次修改后的字典,导致值全部被覆盖为最后一个targetgrp的值。代码中的额外错误:
- 键名大小写不匹配:原数据键为
loadBalancer,代码中写成x2['loadbalancer'](小写b),会触发KeyError; - 目标键名错误:需求生成的键是
loadBalancer和targetgrp,代码中用了albarn和tgarn; - 遍历列表错误:
for tg in x2遍历的是字典的键,而非targetgrp对应的列表值,应改为for tg in x2['targetgrp']; - 列表追加逻辑错误:
arndata.append(finalformattedData)搞反了,正确应为finalformattedData.append(data)。
- 键名大小写不匹配:原数据键为
解决办法
方法1:每次循环创建新字典
先提取loadBalancer和targetgrp的数值,再为每个targetgrp值生成新的字典对象:
albtglist = [[{'loadBalancer': 'LBValue'}, {'targetgrp': ['tg1', 'tg2', 'tg3']}]] finalformattedData = [] for x in albtglist: lb_value = None tg_list = [] # 先提取所需值 for item in x: if 'loadBalancer' in item: lb_value = item['loadBalancer'] if 'targetgrp' in item: tg_list = item['targetgrp'] # 生成每个条目并添加到列表 for tg in tg_list: finalformattedData.append({ 'loadBalancer': lb_value, 'targetgrp': tg }) print(finalformattedData)
方法2:使用字典拷贝
如果需要复用字典结构,每次追加时拷贝字典的副本(浅拷贝即可,此处无嵌套结构):
albtglist = [[{'loadBalancer': 'LBValue'}, {'targetgrp': ['tg1', 'tg2', 'tg3']}]] finalformattedData = [] data = {} for x in albtglist: for item in x: if 'loadBalancer' in item: data['loadBalancer'] = item['loadBalancer'] if 'targetgrp' in item: for tg in item['targetgrp']: data['targetgrp'] = tg # 追加字典副本而非引用 finalformattedData.append(data.copy()) print(finalformattedData)
两种方法运行后都会得到预期输出:
[{'loadBalancer': 'LBValue', 'targetgrp': 'tg1'}, {'loadBalancer': 'LBValue', 'targetgrp': 'tg2'}, {'loadBalancer': 'LBValue', 'targetgrp': 'tg3'}]
内容的提问来源于stack exchange,提问作者siri
相关产品推荐
相关产品推荐

