编写Arithmetic Arranger函数触发TypeError错误求助
问题排查:算术表达式排列函数的类型错误
需求背景
需要实现一个返回算术表达式排列格式的函数arithmetic_arranger:
- 输入
arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])时,输出对齐的表达式格式 - 当第二个参数为
True时,额外显示计算结果
用户代码
def arithmetic_arranger(problems, show = True): #["1 + 3", "1 - a", "1 * 4"] arranged_problems = [] #too many problems supplied if len(problems)>5: return "Error: Too many problems." for i, ele in enumerate(problems): sub = ele.split() num1 = sub[0] oper = sub[1] num2 = sub[2] #appropriate operators "+","-" if sub[1] not in "-+": return "Error: Operator must be '+' or '-'." #only contain digits if sub[0].isdigit() and sub[2].isdigit() is False: return "Error: Numbers must only contain digits." #max 4 digits if len(sub[0])>4 or len(sub[2])>4: return "Error: Numbers cannot be more than four digits." ray = "-" maxlen_line = max(len(num1), len(num2)) ach = maxlen_line + 2 line_num1 = f"{num1:>{ach}}" line_num2 = oper + f"{num2:>{ach-1}}" line_rays = ray*ach try: arranged_problems[0] += (" "*4) + line_num1 except IndexError: arranged_problems.append(line_num1) try: arranged_problems[1] += (" "*4) + line_rays except IndexError: arranged_problems.append(line_rays) try: arranged_problems[2] += (" "*4) + line_num2 except IndexError: arranged_problems.append(line_num2) answ = 0 if oper == "+": answ = int(num1) + int(num2) else: answ = int(num1) - int(num2) line_answ = f"{str(answ):>{ach}}" try: arranged_problems[3] += (" "*4) + line_answ except IndexError: arranged_problems.append(line_answ) if show == True: arranged_problems = f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}\n{arranged_problems[3]}" else: arranged_problems = f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" return arranged_problems
触发错误
Traceback (most recent call last): File "/home/runner/boilerplate-arithmetic-formatter/main.py", line 7, in <module> print(arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])) File "/home/runner/boilerplate-arithmetic-formatter/arithmetic_arranger.py", line 32, in arithmetic_arranger arranged_problems[0] += (" "*4) + line_num1 TypeError: 'str' object does not support item assignment
错误原因
核心问题是变量类型在循环中被意外修改:
- 初始时
arranged_problems是列表,用来存储每一行的内容(数字行、分隔线行、运算符行、结果行) - 第一次循环处理完第一个表达式后,执行了
arranged_problems = f"{...}",将列表直接转换成了字符串 - 第二次循环开始时,
arranged_problems已经是字符串类型,此时尝试arranged_problems[0] += ...,本质是试图修改字符串的索引位置内容,但Python中字符串是不可变类型,不支持这种操作,因此触发TypeError
修复方案
将字符串拼接的逻辑移到循环结束之后,循环过程中始终用列表维护各行内容:
- 循环内只负责将每个表达式的对应行追加到独立的行列表中
- 所有表达式处理完成后,再根据
show参数决定是否包含结果行 - 最后将各行列表用空格连接,再组合成带换行符的最终字符串返回
修正后的代码
def arithmetic_arranger(problems, show=False): # 检查问题数量是否超过限制 if len(problems) > 5: return "Error: Too many problems." # 初始化四行的存储列表 line1 = [] line2 = [] line3 = [] line4 = [] for ele in problems: sub = ele.split() num1 = sub[0] oper = sub[1] num2 = sub[2] # 检查运算符是否合法 if oper not in "-+": return "Error: Operator must be '+' or '-'." # 检查数字是否仅包含数字字符 if not (num1.isdigit() and num2.isdigit()): return "Error: Numbers must only contain digits." # 检查数字长度是否超过4位 if len(num1) > 4 or len(num2) > 4: return "Error: Numbers cannot be more than four digits." maxlen_line = max(len(num1), len(num2)) ach = maxlen_line + 2 # 格式化每一行的内容 line1.append(f"{num1:>{ach}}") line2.append(f"{oper}{num2:>{ach-1}}") line3.append("-" * ach) # 计算结果(如果需要显示) if show: answ = int(num1) + int(num2) if oper == "+" else int(num1) - int(num2) line4.append(f"{str(answ):>{ach}}") # 组合所有行 arranged_problems = [ " ".join(line1), " ".join(line2), " ".join(line3) ] if show: arranged_problems.append(" ".join(line4)) return "\n".join(arranged_problems)
内容的提问来源于stack exchange,提问作者Pablovick
相关产品推荐
相关产品推荐

