You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python彩票号码校验脚本为何未移除含'week x'的错误条目?

彩票号码校验脚本问题排查

我写了一段Python脚本,用来读取文件里的彩票号码行并校验错误。测试数据如下:

week 1;17,19,35,23,8,20,36
week 2;24,28,35,8,3,22
week x;23,29,38,1,35,18,25
week 4;21,2,22,14,4,28,38
week 5;5,37,20,15,3,14,9
week 6;6,29,7,14,16,18,1
week 7;24,31,14,23,4,3,29
week 8;32,21,26,1,15aa,14,17
week 9;8,13,25,12,33,34,35
week 10;29,27,30,13,7,38,26
week 11;34,3,7,24,16,20,38
week 12;15,28,2,29,16,10,8
week 13;32,22,13,14,21,28,26
week 14;37,4,20,3,1,33,10
week 1a5;17,8,38,18,9,32,25

其中第3周(week x)和第15周(week 1a5)因为周数格式错误应该被移除。我用整数校验逻辑处理,但脚本只移除了第15周的条目,没移除第3周的。我加了print True语句,但没触发输出——按说整数校验对'x'和'1a5'都应该抛出错误才对。我想排查这个逻辑的问题,同时弄清楚脚本为啥还遗漏了其他错误。我的脚本代码如下:

def filter_incorrect():
    with open("lottery_numbers.csv") as sourcefile:
        entries = []
        for line in sourcefile:
            line = line.replace("\n","")
            line = line.replace(";",",")
            parts = line.split(",")
            entries.append(parts)
        for result in entries:
            
            try:
                int(result[0].lstrip("week ")) == result[0].lstrip("week ")
                print(result[0] + " True")
                pass
            except:
                entries.remove(result)
                print (len(entries))
            try:
                for i in range(1,len(result)):
                    int(result[i]) == result[i]
                    pass
            except:
                entries.remove(result)
            
            if len(result) != 8:
                entries.remove(result)
            try:
                for i in range(1,len(result)):
                    if int(result[i]) > 39 or int(result[i]) < 1:
                        entries.remove(result)
            except:
                pass
            for i in range(1,len(result)):
                for j in range(1,len(result)):
                    if result[j] == result[i] and i != j:
                        entries.remove(result)
        
        print(len(entries))
        with open("correct_numbers.csv","w") as resultsfile:
            for entry in entries:
                resultsfile.write(f"{entry[0]};{entry[1]},{entry[2]},{entry[3]},{entry[4]},{entry[5]},{entry[6]},{entry[7]}\n")

问题根源分析

1. 遍历列表时直接修改导致元素跳过

这是最关键的问题:你在for result in entries循环里直接调用entries.remove(result),修改了原列表的长度和元素位置。Python的列表迭代器是按索引顺序遍历的,当你删除当前迭代的元素后,列表后续元素会向前移位,迭代器的下一次循环会跳过移位后的下一个元素。比如处理week x时把它移除,原本的第4个元素会变成新的第3个,但迭代器已经走到第4个索引,直接跳过了这个位置的元素,导致week x的后续校验逻辑没执行完全,甚至可能根本没触发移除操作。

2. 周数校验逻辑无效

你写的int(result[0].lstrip("week ")) == result[0].lstrip("week ")完全是多余的:整数和字符串永远不可能相等,这条语句只会返回False,但不会抛出异常——只有当int()转换失败时才会进入except块。不过即使转换失败,因为遍历修改列表的问题,也可能导致元素没被正确移除。

3. 其他校验逻辑的缺陷

  • 号码格式校验:发现无效号码时直接移除元素,同样受遍历修改列表的影响,可能导致错误未被处理。
  • 长度校验:如果元素已经被移除,再判断len(result)会导致逻辑混乱,因为result还是原元素的引用,但列表里已经没有它了。
  • 重复号码校验:嵌套循环里多次触发entries.remove(result),可能导致同一元素被多次移除,引发异常;而且一旦发现重复就移除,没有提前终止循环,浪费资源。

修复后的脚本

解决核心思路:不修改原列表,而是创建新列表存储有效条目,同时重构校验逻辑,让每个校验步骤清晰独立:

def filter_incorrect():
    valid_entries = []
    with open("lottery_numbers.csv") as sourcefile:
        for line in sourcefile:
            line = line.strip()  # 替代replace("\n",""),同时去除首尾空格
            if not line:
                continue  # 跳过空行,避免不必要的错误
            
            # 拆分周数和号码部分,用split(";",1)确保只拆分一次,避免号码里有分号的情况
            try:
                week_part, numbers_part = line.split(";", 1)
            except ValueError:
                print(f"移除格式错误的条目(无分号分隔): {line}")
                continue
            
            # 校验周数格式:必须是"week + 整数"的形式
            try:
                week_num_str = week_part.lstrip("week ").strip()
                int(week_num_str)
            except ValueError:
                print(f"移除周数格式错误的条目: {line}")
                continue
            
            # 拆分号码列表
            numbers = numbers_part.split(",")
            # 校验号码数量是否为7个
            if len(numbers) != 7:
                print(f"移除号码数量错误的条目: {line}")
                continue
            
            # 校验每个号码的合法性:整数、1-39范围、无重复
            valid_numbers = []
            seen_numbers = set()
            has_error = False
            for num_str in numbers:
                num_str = num_str.strip()
                # 校验是否为整数
                try:
                    num = int(num_str)
                except ValueError:
                    print(f"移除号码格式错误的条目: {line}")
                    has_error = True
                    break
                # 校验范围
                if num < 1 or num > 39:
                    print(f"移除号码超出范围的条目: {line}")
                    has_error = True
                    break
                # 校验重复
                if num in seen_numbers:
                    print(f"移除存在重复号码的条目: {line}")
                    has_error = True
                    break
                seen_numbers.add(num)
                valid_numbers.append(num_str)
            
            if has_error:
                continue
            
            # 所有校验通过,加入有效列表
            valid_entries.append((week_part, valid_numbers))
    
    print(f"最终有效条目数量: {len(valid_entries)}")
    # 写入结果文件
    with open("correct_numbers.csv", "w") as resultsfile:
        for week_part, numbers in valid_entries:
            resultsfile.write(f"{week_part};{','.join(numbers)}\n")

# 调用函数执行
filter_incorrect()

修复点说明

  1. 避免遍历修改原列表:用valid_entries收集符合条件的条目,彻底解决迭代器跳过元素的问题。
  2. 周数校验优化:先拆分周数和号码部分,避免把分号换成逗号导致的结构混乱;校验周数时先去除多余空格,确保"week x"这种带空格的错误也能被检测到。
  3. 号码校验逻辑重构:逐个校验号码的格式、范围、重复,一旦发现错误就标记并跳过当前条目,逻辑清晰且高效。
  4. 增加错误提示:每个校验步骤都添加了具体的错误信息,方便排查问题。
  5. 空行处理:自动跳过空行,避免不必要的错误。

内容的提问来源于stack exchange,提问作者Dominic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 12:44:53