为何程序中descriptions与amounts列表长度不一致?
问题:提取Excel交易数据时列表长度不一致的原因与解决办法
场景描述
定义了descriptions和amounts两个列表,用于存储嵌套列表transaction_info(Excel表格每行数据格式为[日期,描述,附加信息,附加信息,金额,余额])的指定元素。运行代码后发现两个列表长度不同,无法对齐进行后续合并,程序处理到第61行前都正常,使用OpenPyxl操作Excel。
原代码
dates = [] descriptions = [] amounts = [] #transaction info is a nested list of each row of my excel sheet transaction_info = select_all(bank_statements) i=0 #skips the first row because of headers for row in transaction_info: if i<1: i+=1 else: #breaks down row cell by cell for cell in row: if cell == row[0]: dates.append(cell) if cell == row[1]: full_desc = str(cell)+str(row[2])+str(row[3]) if 'None' in full_desc: none_strip = full_desc.strip('None') descriptions.append(none_strip) i+=1 elif full_desc in descriptions: descriptions.append(f'{full_desc}{i}') i+=1 else: descriptions.append(full_desc) i+=1 if cell == row[4]: strcell = str(cell) amounts.append(strcell) i+=1
问题原因分析
- 内层循环遍历cell导致重复添加:外层循环已经遍历每一行,内层又遍历该行每个cell,若某行存在多个与
row[0]/row[1]/row[4]值相同的单元格(比如金额和日期数值一致),会触发多次添加操作,导致列表元素数量异常。 - 变量
i的滥用:i同时用于跳过表头和重复描述的计数,多处递增操作打乱了行遍历逻辑,可能导致部分行被重复处理或跳过。 - 单元格值判断逻辑不可靠:直接用
cell == row[x]判断,若单元格是数值类型(如日期、金额),可能因类型/精度问题判断错误;同一行有相同值单元格时,也会重复触发添加。 strip('None')逻辑错误:strip仅移除字符串首尾的指定字符,无法替换中间的"None",导致描述清理不彻底,同时可能间接影响后续重复判断。
修正后的代码
dates = [] descriptions = [] amounts = [] transaction_info = select_all(bank_statements) # 专门用于处理重复描述的计数器,避免和表头控制变量混淆 desc_counter = 1 # 直接通过切片跳过表头行,逻辑更简洁 for row in transaction_info[1:]: # 按固定索引直接获取每行的对应元素,无需遍历cell date = row[0] desc = row[1] extra1 = row[2] extra2 = row[3] amount = row[4] # 添加日期 dates.append(date) # 构建并清理完整描述 full_desc = f"{desc}{extra1}{extra2}" # 替换所有出现的"None",而非仅移除首尾 cleaned_desc = full_desc.replace("None", "") # 处理重复描述 if cleaned_desc in descriptions: cleaned_desc = f"{cleaned_desc}{desc_counter}" desc_counter += 1 descriptions.append(cleaned_desc) # 添加金额 amounts.append(str(amount))
修正说明
- 用
transaction_info[1:]跳过表头,替代原有的i控制逻辑,避免变量冲突。 - 直接通过索引访问固定位置元素,彻底避免内层循环导致的重复添加问题,保证每行对应添加一个日期、描述、金额,三个列表长度完全一致。
- 单独使用
desc_counter处理重复描述,与表头控制分离,逻辑清晰。 - 用
replace("None", "")替换strip('None'),确保所有"None"都被清理,符合需求。
内容的提问来源于stack exchange,提问作者Smitty_Code
相关产品推荐
相关产品推荐

