Python/Sage中序列出现重复值时如何正确终止while循环
代码问题排查
两版旧代码的核心问题出在逻辑顺序和初始值设置上:
- 第一版代码初始化的序列列表为空,没有存入输入的初始参数n,导致初始值完全没被记录;同时循环判断顺序倒置,且return语句里混杂print、append操作,执行逻辑完全不符合预期。
- 第二版代码的循环条件写反,初始n本来就存在于列表中,
while n in my_list会触发异常循环;另外集合判重逻辑只在循环外初始化了一次,循环过程中没有同步更新,根本起不到判重作用,最后返回的是Python内置list类而非存储内容的序列变量。
正确实现方案
核心逻辑按以下顺序编写即可满足需求:
- 初始化序列列表,第一个元素先存入输入的初始值n,同时可以用集合存储已出现的值,把判重的时间复杂度从O(n)降到O(1),长序列运行效率更高
- 进入循环,按奇偶规则计算下一个序列值
- 每次算出新值后先判断是否已经出现过:
- 若已出现:将该重复值追加到序列末尾,立刻终止循环
- 若未出现:将新值追加到序列、更新已出现值集合、把当前n替换为新值,继续下一轮计算
参考实现代码(全整数输出,完全匹配示例结果):
def get_collatz_seq(n): seq = [n] existed = {n} while True: # 按规则计算下一个值 if n % 2 == 0: next_val = n // 2 # 用整数除法避免返回浮点数 else: next_val = 3 * n + 1 # 检测到重复就追加后终止 if next_val in existed: seq.append(next_val) break # 无重复就更新状态继续循环 seq.append(next_val) existed.add(next_val) n = next_val return seq # 测试用例 print(get_collatz_seq(2)) # 输出: [2, 1, 4, 2] print(get_collatz_seq(3)) # 输出: [3, 10, 5, 16, 8, 4, 2, 1, 4]
如果不需要严格的整数格式,把
n//2换回n/2即可正常运行,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Echo7154
相关产品推荐
相关产品推荐

