You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字典列表拆分异常原因排查及代码优化咨询

问题描述

需求:将字典列表中某字段含逗号分隔n个值的字典拆分为n个字典,其余字段保持不变,仅该字段为唯一值。

实际处理后出现异常,输出如下:

before
[{'id': 1, 'time': '1,2,3'}, {'id': 2, 'time': '4,5'}, {'id': 3, 'time': '6'}, {'id': 4, 'time': '7,8,9,10'}]
during
['1', '2', '3']
{'id': 1, 'time': '1'}
{'id': 1, 'time': '2'}
{'id': 1, 'time': '3'}
['4', '5']
{'id': 2, 'time': '4'}
{'id': 2, 'time': '5'}
['7', '8', '9', '10']
{'id': 4, 'time': '7'}
{'id': 4, 'time': '8'}
{'id': 4, 'time': '9'}
{'id': 4, 'time': '10'}
after
{'id': 1, 'time': '3'}
{'id': 2, 'time': '5'}
{'id': 3, 'time': '6'}
{'id': 4, 'time': '10'}
{'id': 1, 'time': '3'}
{'id': 1, 'time': '3'}
{'id': 2, 'time': '5'}
{'id': 4, 'time': '10'}
{'id': 4, 'time': '10'}
{'id': 4, 'time': '10'}

用户代码如下:

meta = [{"id":1,"time":"1,2,3"},{"id":2,"time":"4,5"},{"id":3,"time":"6"},{"id":4,"time":"7,8,9,10"}]
print("before")
print(meta)
meta_copy = meta.copy()
placeholder = meta.copy()

print("during")
for i in range(len(meta)):
    if "," in meta[i]["time"]:
        sub = meta[i]["time"].split(",")
        print(sub)
        for j in range(len(sub)):
            if j == 0:

                meta_copy[i]["time"] = sub[0]
                print(meta_copy[i])
            else:
                placeholder[i]["time"]=sub[j]
                #print(placeholder[i]["time"])
                meta_copy.append(placeholder[i])
                print( meta_copy[-1])
print("after")
for l in range(len(meta_copy)):
    print(meta_copy[l])

请问该异常产生的原因是什么?如何优化代码?


异常原因分析
  1. 浅拷贝导致字典引用共享:meta.copy()是浅拷贝,列表里的字典还是原字典的引用。meta_copy和placeholder里的字典都指向原列表中的同一批字典对象。比如修改placeholder[i]["time"]时,会直接修改这个字典的内容,包括meta_copy里已经存在的同id字典。所以循环到后面的time值时,之前添加到meta_copy里的同id字典的time会被覆盖,最后所有同id的字典都会变成最后一次修改的time值。
  2. 重复添加同一字典引用:当j>0时,你追加的是placeholder[i]这个字典引用,而不是创建新的字典。所以多次追加后,meta_copy里会有多个指向同一字典的条目,后续修改这个字典的time值,所有这些条目都会同步变化。

优化后的代码

直接构建新结果列表,每次创建新字典副本避免引用问题:

meta = [{"id":1,"time":"1,2,3"},{"id":2,"time":"4,5"},{"id":3,"time":"6"},{"id":4,"time":"7,8,9,10"}]
print("before")
print(meta)

result = []
print("during")
for item in meta:
    time_values = item["time"].split(",")
    print(time_values)
    for time_val in time_values:
        # 复制原字典的所有键值对,创建新字典后修改time字段
        new_item = item.copy()
        new_item["time"] = time_val
        result.append(new_item)
        print(new_item)

print("after")
for item in result:
    print(item)

优化说明

  • 遍历原列表每个字典,拆分time字段后,为每个time值创建新的字典副本,彻底避免引用共享问题
  • 逻辑更直接,直接构建结果列表,不需要维护原列表的拷贝和占位符,减少出错可能
  • 输出结果完全符合需求:每个拆分后的字典都是独立对象,time字段为唯一值,其余字段保持不变

内容的提问来源于stack exchange,提问作者BumblingBabblingBaboon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:24:51