python-3.x - 使用对象动态构建列表
问题描述
我正在构建一个 SP 500 组件列表以将其保存在泡菜中。
我从代码中的链接获取项目,然后获取我想要的信息并为每个项目构建一个对象。
这就是问题所在——>然后我想将每个对象保存到一个列表中,以便将来迭代。
该列表仅存储循环的最后一个对象,而不是存储每个显示的对象。
这样做应该相当容易,但我似乎无法找到为什么会发生这种情况的答案
def save_sp500_tickers():
resp = requests.get(
'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
soup = bs.BeautifulSoup(resp.text, "lxml")
table = soup.find('table', {'class': 'wikitable sortable'})
components = []
data = {}
for row in table.findAll('tr')[1:]:
ticker = row.findAll('td')[0].text.replace('\n', '') # AAPL
name = row.findAll('td')[1].text.replace('\n', '') # Apple Inc
sector = row.findAll('td')[3].text.replace('\n', '') # Information Technology
mapping = str.maketrans(".", "-")
ticker = ticker.translate(mapping)
name = name.translate(mapping)
sector = sector.translate(mapping)
data['ticker']=ticker
data['name']=name
data['sector']=sector
print(data) # {'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'}
components.append(data) # I add each component to the list
with open("SP500components.pickle", "wb") as f:
pickle.dump(components, f)
print(components) # this gives me the list with only the last item repeated
return components
save_sp500_tickers()
目标是有一个如下所示的列表:
[{'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'},
{'ticker': 'ETN', 'name': 'Eaton Corporation', 'sector': 'Industrials'},
{'ticker': 'EBAY', 'name': 'eBay Inc-', 'sector': 'Consumer Discretionary'},
{'ticker': 'ECL', 'name': 'Ecolab Inc-', 'sector': 'Materials'},
{'ticker': 'EIX', 'name': "Edison Int'l", 'sector': 'Utilities'},
...,
...]
相反,我得到一个仅多次显示最后一个对象的列表,如下所示:
[{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
...,
...]
解决方案
这完全取决于您的data
对象。您在 for 循环之外对其进行初始化。由于它是一个字典,它在 python 中是可变的,当你将它附加到列表时,你只是data
在循环的每次迭代中附加一个对该字典的引用,而不是一个新的字典。所以最后引用只是指向字典的最新版本,因此为什么它多次出现是同一个字典 - 它是同一个字典。
此页面可能有助于了解正在发生的事情。
尝试在 for 循环中移动 dict 的初始化:
def save_sp500_tickers():
resp = requests.get(
'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
soup = bs.BeautifulSoup(resp.text, "lxml")
table = soup.find('table', {'class': 'wikitable sortable'})
components = []
for row in table.findAll('tr')[1:]:
ticker = row.findAll('td')[0].text.replace('\n', '') # AAPL
name = row.findAll('td')[1].text.replace('\n', '') # Apple Inc
sector = row.findAll('td')[3].text.replace('\n', '') # Information Technology
mapping = str.maketrans(".", "-")
ticker = ticker.translate(mapping)
name = name.translate(mapping)
sector = sector.translate(mapping)
data = dict(ticker=ticker, name=name, sector=sector)
print(data) # {'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'}
components.append(data) # I add each component to the list
with open("SP500components.pickle", "wb") as f:
pickle.dump(components, f)
print(components) # this gives me the list with only the last item repeated
return components
推荐阅读
- c# - 等待用户点击多个控件中的一个控件
- javascript - REST API 新用户未发布到 MongoDB
- visual-studio-code - 安装扩展时VSCode扩展依赖安装
- javascript - 如何在 React.js 组件中执行脚本?
- asp.net-core-webapi - 如何处理带有客户消息的错误请求 Web api 核心?
- redirect - IIS 重定向 - 重定向到新站点,特定页面除外
- python-3.x - 在python中按属性值过滤类列表
- vue.js - 在 JavaScript 文件中导入 Vue 路由器会导致“模块解析失败”错误
- c++ - 这是 g++ 还是 CLion 错误(在 CLion 中使用 Ctrl+D)?
- python - Google Cloud Logging 因云功能而出现故障