Python中如何仅更新字典列表中指定元素的特定键值?
问题原因与解决方法
问题根源
你遇到的问题是因为所有列表元素都指向同一个字典对象。在get_compression_stats函数中,meta = {}是在循环外定义的,每次循环只是修改这个字典的键值对,然后将同一个字典引用添加到result列表中。所以列表里的所有元素本质上是同一个字典,修改其中任意一个的Stack Pos,其他元素也会跟着变化。
解决办法
有两种简单的修复方式:
方式1:在循环内创建新字典
把meta的定义移到最内层循环里,每次迭代都新建一个字典:
def get_compression_stats(img): result = [] r = range(0,len(img)) i_e, r_avg_e, r_median_e = get_entropy(img,r) comp_parameters = {'typesize':4} filter_names = ['NONE','SHUFFLE','BITSHUFFLE','BYTEDELTA','SHUFFLE+BYTEDELTA','BITSHUFFLE+BYTEDELTA','SHUFFLE+BITSHUFFLE+BYTEDELTA'] rows_for_blocksize = [0,1,64] for c in blosc2.compressor_list(): print("Codec: "+str(c)) comp_parameters['codec'] = c for f in filter_names: print("Filter: "+f) comp_parameters['filters'] = get_filter_array(f) for r in rows_for_blocksize: # 每次循环新建一个空字典 meta = {} comp_parameters['blocksize'] = r*img.shape[1]*img[0][0].nbytes print("Blocksize: "+ str(comp_parameters['blocksize'])) i_u8 = get_ubyte_img(img) c_img = blosc2.compress2(i_u8,**comp_parameters) orig_len, comp_len, blk_size = blosc2.get_cbuffer_sizes(c_img) c_ratio = comp_len/orig_len meta['Img Entropy'] = i_e meta['Avg Row Entropy'] = r_avg_e meta['Comp Size, B'] = comp_len meta['COMP RATIO, out/in'] = c_ratio print("Comp Ratio, out/in: "+ str(c_ratio)) result.append(meta) return(result)
方式2:添加字典副本到列表
如果不想移动meta的定义,每次append时添加字典的副本:
# 替换原代码中的result.append(meta)为: result.append(meta.copy())
或者用dict(meta)创建新字典:
result.append(dict(meta))
修复后,列表中的每个元素都是独立的字典对象,此时执行result[-2]['Stack Pos'] = 10就只会修改倒数第二个元素的Stack Pos值,不会影响其他元素。
内容的提问来源于stack exchange,提问作者shparekh
相关产品推荐
相关产品推荐

