Python嵌套字典更新异常:指定子字典更新却同步修改所有子字典
嵌套字典同步修改问题:爬虫数据存入字典时所有子字典被同步更新
使用BeautifulSoup抓取网页表格数据,遍历行与单元格提取车手名称和圈速,试图存入嵌套字典。但运行时发现,更新指定一级键对应的二级字典后,所有一级键的二级字典都被同步修改。
代码示例
# Imports import requests from bs4 import BeautifulSoup as bsoup dataurls = { 'race1': 'https://fiaresultsandstatistics.motorsportstats.com/results/2022-bahrain-grand-prix/classification/2c65d50d-606e-4988-81c5-7a4976ef0e6f' } # Setup the dictionary races = ['race1', 'race2'] drivers = ['driver1', 'driver2'] mainDict = dict.fromkeys(races, {}) # Scraping elements def webscraper(mDict, race): soup = bsoup(requests.get(dataurls[race]).content, "html.parser") # Dict for races, will contain driver key and lap time value. rDict = {} # Parse the table by row, extract driver name and lap time for tr in soup.find("table", class_="_2Q90P").find_all("tr", class_="_3AoAU"): row = ([td.text for td in tr.find_all('td')]) dDriver = row[2] dTime = row[6] dDict = {dDriver: dTime} rDict.update(dDict) mDict[race].update(rDict) webscraper(mainDict, races[0]) print(mainDict)
预期输出
{ 'race1': {'driver1': '1:30:100', 'driver2': '1:30.200'}, 'race2': {} }
实际输出
{ 'race1': {'driver1': '1:30:100', 'driver2': '1:30.200'}, 'race2': {'driver1': '1:30:100', 'driver2': '1:30.200'} }
问题根源
dict.fromkeys(races, {}) 初始化字典时,所有一级键指向的是同一个空字典对象。也就是说,mainDict['race1']和mainDict['race2']引用的是内存中的同一个字典实例,修改其中一个,另一个自然会同步变化。
解决方法
用字典推导式初始化mainDict,为每个赛事创建独立的空字典:
mainDict = {race: {} for race in races}
修改后重新运行代码,即可得到符合预期的输出:race1包含抓取到的车手数据,race2保持空字典。
补充方案
如果不想修改初始化逻辑,也可以在webscraper函数中提前检查并创建独立字典:
def webscraper(mDict, race): # 确保当前赛事对应独立字典 if race not in mDict or not isinstance(mDict[race], dict): mDict[race] = {} soup = bsoup(requests.get(dataurls[race]).content, "html.parser") rDict = {} for tr in soup.find("table", class_="_2Q90P").find_all("tr", class_="_3AoAU"): row = ([td.text for td in tr.find_all('td')]) dDriver = row[2] dTime = row[6] rDict[dDriver] = dTime mDict[race].update(rDict)
不过字典推导式的方式更简洁高效,是此类场景的首选方案。
内容的提问来源于stack exchange,提问作者CleanGiant
相关产品推荐
相关产品推荐

