Python列表添加字典元素时所有已有元素被覆盖的问题
问题
我尝试创建一个字典列表,这本应非常简单。我的代码可以正确添加新元素,但同时会将列表中所有已有的元素更新为相同的值。我忽略了什么?
原代码:
while y < search_repo_count: search_repo_name = search_results[n]["items"][y]["repository"]["name"] if team_repo_name == search_repo_name: print("Search Repo Name: " + search_repo_name + " Team Repo Name: " + team_repo_name + " y: " + str(y) + " z: " + str(z)) search_match["repo_name"] = search_repo_name search_match["repo_url"] = search_results[n]["items"][y]["repository"]["html_url"] search_match["result_url"] = search_results[n]["items"][y]["html_url"] print(search_match) # 这里输出符合预期 final_output.append(search_match) # 这里会插入新的search_match,但同时把列表里所有已有元素也改成这个值 print(final_output) z = z + 1 else: print("No Match") y = y + 1
运行结果:
repo_abc被正常插入final_output,repo_def作为新搜索值被插入时,之前的值也被覆盖成了repo_def。我期望第一个值保持不变,只添加新值作为新记录。
Search Repo Name: repo_abc Team Repo Name: repo_abc y: 7 z: 1 {'repo_name': 'repo_abc', 'repo_url': 'https://github.aexp.com/this-org/repo_abc', 'result_url': 'https://github.aexp.com/this-org/repo_abc/blob/f7bd013c7d72136dfb70a7ed4ae07a947768e0bd/src/main/java/com/aexp/team-a/nmi/NMICalculator.scala'} [{'repo_name': 'repo_abc', 'repo_url': 'https://github.aexp.com/this-org/repo_abc', 'result_url': 'https://github.aexp.com/this-org/repo_abc/blob/f7bd013c7d72136dfb70a7ed4ae07a947768e0bd/src/main/java/com/aexp/team-a/nmi/NMICalculator.scala'}, {'repo_name': 'repo_abc', 'repo_url': 'https://github.aexp.com/this-org/repo_abc', 'result_url': 'https://github.aexp.com/this-org/repo_abc/blob/f7bd013c7d72136dfb70a7ed4ae07a947768e0bd/src/main/java/com/aexp/team-a/nmi/NMICalculator.scala'}] ... Search Repo Name: repo_def Team Repo Name: repo_def y: 11 z: 2 {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh'} [{'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh'}, {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh'}, {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh'}] Search Repo Name: repo_def Team Repo Name: repo_def y: 12 z: 3 {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh_org'} [{'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh_org'}, {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh_org'}, {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh_org'}, {'repo_name': 'repo_def', 'repo_url': 'https://github.aexp.com/this-org/repo_def', 'result_url': 'https://github.aexp.com/this-org/repo_def/blob/58769c59d6c1af2457b43dfaaf21c4ba2fb22594/ob-crmd-myca/scripts/myca_ob_ext.sh_org'}]
我还试过用final_output[z] = search_match和final_output.insert(n, search_match)更新列表,结果一样;把final_output改成字典也没用。
解决方法
问题出在字典是可变对象,你一直在复用同一个search_match字典。每次修改它的键值对时,列表里之前添加的所有引用都会指向这个同一个字典,所以所有元素都会跟着变。
要解决这个问题,每次匹配到新结果时,都要创建一个新的字典,而不是修改同一个旧字典。修改后的代码如下:
while y < search_repo_count: search_repo_name = search_results[n]["items"][y]["repository"]["name"] if team_repo_name == search_repo_name: print("Search Repo Name: " + search_repo_name + " Team Repo Name: " + team_repo_name + " y: " + str(y) + " z: " + str(z)) # 每次循环创建新字典,而不是复用旧的 search_match = { "repo_name": search_repo_name, "repo_url": search_results[n]["items"][y]["repository"]["html_url"], "result_url": search_results[n]["items"][y]["html_url"] } print(search_match) final_output.append(search_match) print(final_output) z = z + 1 else: print("No Match") y = y + 1
这样每次添加到列表里的都是独立的新字典,修改新字典不会影响之前已经添加的元素。
内容的提问来源于stack exchange,提问作者fiffer1
相关产品推荐
相关产品推荐

