向列表追加字典并修改值后,列表中所有字典同步变化的问题求助
问题解决:列表中字典引用导致的重复修改问题
问题重现
你尝试向列表中先追加一个字典,修改字典值后再次追加,期望得到两个仅一个值不同的字典,但实际两个字典的对应值都被修改了。
原代码:
details = [] string1 = 'I want some information from this string in a dictionary' string2 = 'A short string' row = {'first_word': string1.split(' ')[0], 'last_word': string1.split(' ')[-1], 'length_string': len(string1)} details.append(row) if len(string2) < 50: row['length_string'] = 'String2 is too short.' details.append(row) for x in details: print(x)
执行后输出:
{'first_word': 'I', 'last_word': 'dictionary', 'length_string': 'String2 is too short.'} {'first_word': 'I', 'last_word': 'dictionary', 'length_string': 'String2 is too short.'}
期望输出:
{'first_word': 'I', 'last_word': 'dictionary', 'length_string': 56} {'first_word': 'I', 'last_word': 'dictionary', 'length_string': 'String2 is too short.'}
问题原因
Python中字典是可变对象,当你执行details.append(row)时,列表中存储的是该字典的引用,而不是字典的副本。所以后续修改row的内容时,列表中所有指向这个引用的元素都会跟着变化——本质上列表里的两个元素指向的是同一个字典对象。
解决方案
要解决这个问题,需要在第二次追加前创建原字典的副本,让列表中的两个元素指向不同的字典对象。有两种常用方式:
方法1:创建新字典
修改代码,在修改值前重新生成一个新字典(或基于原字典复制后修改):
details = [] string1 = 'I want some information from this string in a dictionary' string2 = 'A short string' # 第一个字典 row = {'first_word': string1.split(' ')[0], 'last_word': string1.split(' ')[-1], 'length_string': len(string1)} details.append(row) if len(string2) < 50: # 创建新字典,复用原有键值,修改目标字段 new_row = { 'first_word': row['first_word'], 'last_word': row['last_word'], 'length_string': 'String2 is too short.' } details.append(new_row) for x in details: print(x)
方法2:使用字典的copy()方法
利用字典内置的copy()方法生成副本,修改副本后再追加:
details = [] string1 = 'I want some information from this string in a dictionary' string2 = 'A short string' row = {'first_word': string1.split(' ')[0], 'last_word': string1.split(' ')[-1], 'length_string': len(string1)} details.append(row) if len(string2) < 50: # 生成原字典的副本 row_copy = row.copy() row_copy['length_string'] = 'String2 is too short.' details.append(row_copy) for x in details: print(x)
两种方法执行后都会得到你期望的输出。
内容的提问来源于stack exchange,提问作者MaxK
相关产品推荐
相关产品推荐

