请求修复openStructure递归函数:遍历嵌套结构汇总MO数据
问题:递归遍历嵌套表格结构收集MO数据失败,需修复递归逻辑
需求背景
我有一个由数值和嵌套结构构成的列表结构,结构内部可继续包含数值与其他嵌套结构,该结构基于HTML解析器实现,用于提取表格数据。需要遍历所有分支并收集其中的目标MO类型数据,设计了递归函数openStructure但递归逻辑存在问题,无法正常完成数据汇总,请求修复。
相关代码
HTML解析函数
def getPage(item): url = '' round_url = f'{url}{item}' page = requests.get(round_url) return BeautifulSoup(page.content, "html.parser")
表格数据提取函数
def getTable(page): table = page.find("table", id="customers") cod = [] qt = [] un = [] typ = [] iRow = 0 checkRows = table.find_all('tr') if checkRows: for row in table.find_all('tr'): iColumn = 0 for column in row.find_all('td'): if iRow > 0: parser = column.text.split() if iColumn == 0: cod.append(parser[0]) if iColumn == 1: length = len(parser) typ.append(parser[length-1]) un.append(parser[length-2]) qt.append(parser[length-3]) iColumn += 1 iRow += 1 return cod, qt, un, typ
MO类型数据汇总函数(原逻辑有问题)
def getMO(cod, qt, un, typ): aux_mo_index = 0 mo_index = [] for mo in typ: if mo == 'MO': mo_index += [aux_mo_index] aux_mo_index += 1 mo_cod = [] mo_qt = [] i_index = 0 for i in mo_index: aux_mo = cod[i] if aux_mo in mo_cod: mo_qt[i_index] += qt[i_index] else: mo_cod.append(aux_mo) mo_qt.append(qt[i]) i_index += 1 return mo_cod, mo_qt
嵌套结构检测函数(原返回值有问题)
def getStructures(cod, qt, un, typ): sp_index = [] aux_sp_index = 0 for sp in typ: if sp == 'SP': sp_index += [aux_sp_index] aux_sp_index += 1 structure = [] if not sp_index: return 0 else: for i in sp_index: structure.append(cod[i]) return structure
递归遍历函数(存在问题)
def openStructure(id, mo_cod, mo_qt): cod, qt, un, typ = getTable(getPage(id)) x, y = getMO(cod, qt, un, typ) mo_cod += x mo_qt += y structures_left = getStructures(cod, qt, un, typ) if not structures_left: return mo_cod, mo_qt else: for i in structures_left: return openStructure(i, mo_cod, mo_qt)
输入输出示例
getTable()输出:['00200190', '00120173', '00200189', '00200188', '00120174', '00120172', 'MO0004', 'MO0003', 'MO0002', 'MO0001'] ['2,0000', '1,0000', '1,0000', '1,0000', '3,0000', '2,0000', '1,0000', '1,0000', '1,0000', '3,0000'] ['PC', 'PC', 'PC', 'PC', 'PC', 'PC', 'HR', 'HR', 'HR', 'HR'] ['SP', 'SP', 'SP', 'SP', 'SP', 'SP', 'MO', 'MO', 'MO', 'MO']getMO()输出:['MO0004', 'MO0003', 'MO0002', 'MO0001'] ['1,0000', '1,0000', '1,0000', '3,0000']getStructures()输出:['00200190', '00120173', '00200189', '00200188', '00120174', '00120172']
问题分析
- 递归函数提前终止:
openStructure中遍历嵌套结构时,第一次递归就执行return,导致仅处理第一个SP分支,后续所有嵌套结构都被跳过。 - 空结构判断逻辑错误:
getStructures在无SP结构时返回0,而if not structures_left:会将0视为False,导致逻辑判断混乱(实际应返回空列表,保证判断一致性)。 - MO数量累加错误:
getMO中直接对字符串类型的数量执行+=操作,会导致字符串拼接而非数值累加;同时查找重复编码的索引逻辑错误,导致累加位置错位。
修复后的代码
修复嵌套结构检测函数
def getStructures(cod, qt, un, typ): sp_index = [] # 用enumerate简化索引计数 for idx, typ_item in enumerate(typ): if typ_item == 'SP': sp_index.append(idx) structure = [cod[i] for i in sp_index] return structure
修复MO类型数据汇总函数
def getMO(cod, qt, un, typ): mo_cod = [] mo_qt = [] for cod_item, qt_item, typ_item in zip(cod, qt, typ): if typ_item == 'MO': if cod_item in mo_cod: # 找到重复编码的索引,转换为数值累加后转回字符串格式 idx = mo_cod.index(cod_item) current_val = float(mo_qt[idx].replace(',', '.')) add_val = float(qt_item.replace(',', '.')) mo_qt[idx] = f"{current_val + add_val:.4f}".replace('.', ',') else: mo_cod.append(cod_item) mo_qt.append(qt_item) return mo_cod, mo_qt
修复递归遍历函数
def openStructure(id, mo_cod=None, mo_qt=None): # 初始化默认参数,避免调用时必须传入空列表 if mo_cod is None: mo_cod = [] if mo_qt is None: mo_qt = [] cod, qt, un, typ = getTable(getPage(id)) current_mo_cod, current_mo_qt = getMO(cod, qt, un, typ) # 合并当前页面的MO数据,处理重复编码的累加 for cod_item, qt_item in zip(current_mo_cod, current_mo_qt): if cod_item in mo_cod: idx = mo_cod.index(cod_item) current_val = float(mo_qt[idx].replace(',', '.')) add_val = float(qt_item.replace(',', '.')) mo_qt[idx] = f"{current_val + add_val:.4f}".replace('.', ',') else: mo_cod.append(cod_item) mo_qt.append(qt_item) structures_left = getStructures(cod, qt, un, typ) # 遍历所有嵌套结构,递归处理 if structures_left: for i in structures_left: openStructure(i, mo_cod, mo_qt) return mo_cod, mo_qt
使用说明
调用修复后的openStructure时,只需传入初始ID即可,无需手动传入空列表:
final_mo_cod, final_mo_qt = openStructure("初始ID")
内容的提问来源于stack exchange,提问作者Gustavo Castilho
相关产品推荐
相关产品推荐

