双元素元组键字典转wi为键列表值字典及代码错误排查
错误原因
代码的核心问题是列表是Python中的可变对象:你在全局仅初始化了一次y_t = [],后续每次循环调用y_t.clear()都是清空同一个内存地址的列表对象,而y_w['w{0}'.format(w)]=y_t是把该列表的引用赋值给字典的键,本质上y_w['w1']和y_w['w2']指向的是内存中完全相同的列表。最后一次循环修改列表内容后,两个键对应的取值都会同步变成最后一次的结果。
如果要保留你原有代码的逻辑,只需要把y_t.clear()替换为每次循环内新建独立空列表即可,修改后代码如下:
y={('t1', 'w1'): 1, ('t2', 'w1'): 2, ('t3', 'w1'): 3, ('t1', 'w2'): 4, ('t2', 'w2'): 5, ('t3', 'w2'): 6} y_w={} for w in range(1,3): y_t = [] # 每次循环新建独立列表,避免引用共用 for t in range(1,4): y_t.append(y[f't{t}', f'w{w}']) y_w[f'w{w}'] = y_t print(y_w)
更简洁的实现方法
不需要硬编码t、w的数值范围,适配任意数量的ti、wi场景,推荐两种实现:
方法1:使用collections.defaultdict(推荐,效率最高)
仅需遍历一次原字典即可完成转换,时间复杂度O(n),逻辑直观易读:
from collections import defaultdict y = {('t1', 'w1'): 1, ('t2', 'w1'): 2, ('t3', 'w1'): 3, ('t1', 'w2'): 4, ('t2', 'w2'): 5, ('t3', 'w2'): 6} res = defaultdict(list) for (ti, wi), val in y.items(): res[wi].append(val) # 如需转为普通字典,可执行 res = dict(res) print(res)
方法2:纯字典推导式(无需导入库,一行实现)
适合小数据量场景,无需导入额外模块:
y = {('t1', 'w1'): 1, ('t2', 'w1'): 2, ('t3', 'w1'): 3, ('t1', 'w2'): 4, ('t2', 'w2'): 5, ('t3', 'w2'): 6} res = {wi: [y[(ti, wi)] for ti in {k[0] for k in y}] for wi in {k[1] for k in y}} print(res)
内容的提问来源于stack exchange,提问作者errenmike1806
相关产品推荐
相关产品推荐

