递归结合for循环异常:调用函数时循环变量i未从0开始
问题分析与修复方案
核心问题点
- 参数误用:循环遍历范围写了
range(len(snake_length)),但snake_length是表示蛇长度的整数,len()对整数调用本身就会报错。从你的输出逻辑看,实际需要遍历所有历史坐标,应该用range(len(history_x))(history_x和history_y存储了所有已用坐标)。 - 递归未终止当前流程:检测到坐标重复时调用递归,但递归结束后当前函数会继续执行后续的
RANDOM.insert操作,导致重复的旧坐标也被插入列表,同时递归生成的新坐标也会插入,造成数据混乱。 - 递归无返回处理:递归调用生成的新坐标没有被当前函数接收,当前函数仍会使用最初生成的重复坐标执行后续步骤,完全失去了递归的意义。
修复后的代码(推荐用循环替代递归,更易理解)
递归在这里不是必要的,用循环重复生成坐标直到找到未使用的更简单:
import random def get_rand(x, y, history_x, history_y, RANDOM): while True: rand_x = random.randrange(0, x) rand_y = random.randrange(0, y) # 检查坐标是否在历史列表中 is_used = False for i in range(len(history_x)): if rand_x == history_x[i] and rand_y == history_y[i]: is_used = True break if not is_used: # 找到可用坐标,插入并退出循环 RANDOM.insert(0, rand_y) RANDOM.insert(0, rand_x) break
如果坚持用递归的正确写法
如果一定要用递归,需要在发现重复时返回递归结果,并且终止当前函数的后续执行:
import random def get_rand(x, y, history_x, history_y, RANDOM): rand_x = random.randrange(0, x) rand_y = random.randrange(0, y) # 遍历所有历史坐标检查重复 for i in range(len(history_x)): if rand_x == history_x[i] and rand_y == history_y[i]: # 发现重复,递归调用后直接返回,不执行后续insert return get_rand(x, y, history_x, history_y, RANDOM) # 没有重复,插入坐标 RANDOM.insert(0, rand_y) RANDOM.insert(0, rand_x)
额外优化建议
- 把历史坐标存储为元组的集合(比如
used_coords = {(x1,y1), (x2,y2)}),检查重复的效率会更高,不需要循环遍历,直接用(rand_x, rand_y) in used_coords判断,代码更简洁:
import random def get_rand(x, y, used_coords, RANDOM): while True: rand_x = random.randrange(0, x) rand_y = random.randrange(0, y) if (rand_x, rand_y) not in used_coords: RANDOM.insert(0, rand_y) RANDOM.insert(0, rand_x) used_coords.add((rand_x, rand_y)) break
调用时需要把history_x和history_y转换成集合,比如used_coords = set(zip(history_x, history_y))。
内容的提问来源于stack exchange,提问作者Noflik
相关产品推荐
相关产品推荐

