Codewars Dashatize It挑战代码报错:NameError: name 'N' is not defined
问题描述
我在解决Codewars的Dashatize It挑战,需求如下:
- 若输入
n是整数,返回在每个奇数前后添加短横线但首尾无短横线的字符串; - 负数需移除负号;
- 非整数返回
"NaN"。
示例:dashatize(6815) -> '68-1-5'
但测试时传入None触发了NameError,报错栈显示问题出在使用eval处理字符的环节,代码和报错信息如下:
我的代码
def dashatize(n): make_string = str(n) make_list = list(make_string.strip()) make_list_int = [eval(i) for i in make_list] test = [] result = [] final_result_2 = None make_list_int.append(1) if n == None: pass else: for number in make_list_int: positions_odd_or_even = [] for a in range(len(test)): if test[a] == "odd": positions_odd_or_even.append(a) if (number % 2) == 0: test.append("even") position = make_list_int.index(number) kesel = make_list_int[position] + make_list_int[position+1] if (kesel % 2) > 0: result.insert(position+1, str(number) + "-") if (kesel % 2) == 0: result.insert(position, str(number)) if (number % 2) >= 1: test.append("odd") position = make_list_int.index(number) result.insert(position+1, str(number) + "-") final_result_1 = ''.join(result) final_result_2 = final_result_1[:-3] return final_result_2
报错信息
Traceback (most recent call last): File "/workspace/default/tests.py", line 13, in <module> test.assert_equals(dashatize(None),"None", "Should return None"); ^^^^^^^^^^^^^^^ File "/workspace/default/solution.py", line 4, in dashatize make_list_int = [eval(i) for i in make_list] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/workspace/default/solution.py", line 4, in <listcomp> make_list_int = [eval(i) for i in make_list] ^^^^^^^ File "<string>", line 1, in <module> NameError: name 'N' is not defined
修复方案
问题根源
- 传入
None时,str(None)会生成字符串"None",遍历后得到字符'N',用eval('N')会尝试查找名为N的变量,直接触发NameError。 - 原代码逻辑冗余复杂,比如
make_list_int.index(number)会返回第一个匹配项,导致重复数字处理错误,同时完全没处理非整数输入的校验逻辑。
修复步骤
- 先做输入校验:
- 排除布尔值(因为
bool是int子类,但不属于挑战要求的整数范畴); - 尝试将输入转为整数,失败则直接返回
"NaN";
- 排除布尔值(因为
- 替换危险的
eval:用int(i)安全转换字符,同时通过取绝对值去掉负号; - 简化核心逻辑:遍历每个数字,判断是否为奇数,按需添加横线,最后处理可能的连续横线和首尾多余横线。
修正后的代码
def dashatize(n): # 排除布尔值,因为bool属于int子类但不是有效输入 if isinstance(n, bool): return "NaN" # 尝试将输入转为整数,处理float类型的整数(如5.0) try: num = int(n) except (TypeError, ValueError): return "NaN" # 转为绝对值的字符串,自动去掉负号 s = str(abs(num)) result = [] for idx, char in enumerate(s): digit = int(char) if digit % 2 == 1: # 奇数:不是第一个字符则前面加横线 if idx > 0: result.append('-') result.append(char) # 不是最后一个字符则后面加横线 if idx < len(s) - 1: result.append('-') else: result.append(char) # 处理相邻奇数产生的连续横线,再确保首尾无横线 final_str = ''.join(result).replace('--', '-').strip('-') return final_str
测试验证
dashatize(6815)→'68-1-5'(符合示例)dashatize(None)→'NaN'(正确处理非整数输入)dashatize(-28369)→'28-3-6-9'(自动移除负号)dashatize(274)→'2-7-4'(正确添加横线)dashatize("abc")→'NaN'(非整数返回NaN)
内容的提问来源于stack exchange,提问作者Chritz
相关产品推荐
相关产品推荐

