遍历pandas DataFrame按增删记录维护列表历史时触发list.remove值不存在错误求解
代码报错的核心原因
1. 空值判断失效触发移除报错
pandas默认读取的空单元格是np.nan类型,不是Python原生的空字符串''。Python中np.nan与任何值做不等判断都会返回True,哪怕判断的对象就是它自己。
你当前的判断逻辑df.iloc[count].added != ''根本无法识别空值:循环走到第1行(索引1)时,added列是NaN,判断条件会误判为真,代码会尝试从初始股票列表中移除NaN值——因为列表里不存在这个值,直接抛出ValueError: list.remove(x) not in list。
2. 列表方法的返回值与引用认知错误
Python的list.remove()、list.append()都是原地修改列表的方法,执行完成后没有返回值(即默认返回None)。
哪怕空值判断逻辑正确,你把这两个方法的返回值赋值给new变量,最后store里存的全是None,根本没法记录每一步操作后的列表快照。如果图省事直接把原列表存入store,还会踩可变对象的坑:list是Python的可变引用类型,store里存的不是列表的内容,而是列表的内存地址,后续原地修改列表时,之前存入的所有快照都会被同步改成最新值,最后所有行的history列内容完全相同。
修正后的实现方案
核心调整点:
- 用pandas内置的
pd.notna()判断单元格是否为空,替代和空字符串比较的逻辑 - 每次增删操作完成后,存入当前列表的副本(用
list.copy()方法),避免引用污染 - 取消给
remove/append方法赋值的错误逻辑
import pandas as pd import numpy as np # 初始股票列表 current_holdings = ['AAPL', 'AAL', 'MPWR', 'TRMB'] # 构造测试DataFrame,空值对应pandas默认的nan类型 df = pd.DataFrame({ 'added': ['MPWR', np.nan, np.nan, 'TRMB', np.nan], 'removed': [np.nan, 'FTI', 'CXO', np.nan, 'TIF'] }) history_list = [] for _, row in df.iterrows(): # 对应原业务逻辑:added列非空时移除该标的 if pd.notna(row['added']): current_holdings.remove(row['added']) # removed列非空时新增该标的 if pd.notna(row['removed']): current_holdings.append(row['removed']) # 存入当前持仓的副本,避免引用问题 history_list.append(current_holdings.copy()) # 给df新增history列 df['history'] = history_list
运行完成后得到的df和预期格式完全一致。
内容的提问来源于stack exchange,提问作者finmathstudent
相关产品推荐
相关产品推荐

