Python列表重复项提取问题排查:无法识别全部重复记录
看起来你遇到的核心问题有两个:数据拆分逻辑的小瑕疵,以及重复项统计时的逻辑错误,导致无法正确识别所有重复的数值列表。让我们一步步拆解和修复:
一、先修正数据拆分代码的问题
你的当前拆分逻辑[k for k in n if not k.isdigit()]存在两个漏洞:
- 无法处理带空格的数字(比如
" 2"),isdigit()会返回False,导致本应进入good的行被误判到wrong - 空字符串(比如
3,,4,5,6中的空值)处理逻辑没问题,但需要先清理每个元素的首尾空格,避免干扰判断
修正后的拆分代码:
wrong = [] good = [] good_dups = [] wrong_dups = [] # 读取Listy.txt内容 with open("Listy.txt", "r") as f: content = f.readlines() for line in content: line = line.strip() # 去掉行首尾的换行符和空格 if not line: continue # 跳过空行 parts = line.split(',') is_valid = True cleaned_parts = [] for part in parts: p = part.strip() if not p: # 空字符串(逗号连续的情况) is_valid = False break if not p.isdigit(): # 只保留纯数字项 is_valid = False break cleaned_parts.append(p) if is_valid: good.append(cleaned_parts) else: wrong.append(parts) # 修正打印文案(原代码把正确行标成了Error Syntax) print(f"There are: {len(wrong)} error lines") for i, val in enumerate(wrong): print('Error Line', i+1, *val, sep=" ") print() print(f"There are: {len(good)} correct lines") for i, val in enumerate(good): print('Correct Line', i+1, *val, sep=" ") print()
这段代码会正确把2,3,1、2,3,1、1,2,3这些行都纳入good列表。
二、修复重复项统计的核心逻辑
你当前的重复项统计代码有个致命问题:你对循环变量x进行了排序,但原good列表中的元素还是未排序的,所以good.count(x)根本找不到匹配项。比如['2','3','1']排序后变成['1','2','3'],但原good里没有这个排序后的列表,count自然返回0,无法触发添加逻辑。
正确的做法是先统计每个排序后列表的出现次数(用元组作为字典的键,因为列表不可哈希),再根据统计结果收集所有重复项:
# 第一步:统计每个排序后列表的出现次数 count_map = {} for item in good: sorted_tuple = tuple(sorted(item)) # 转成元组才能作为字典键 count_map[sorted_tuple] = count_map.get(sorted_tuple, 0) + 1 # 第二步:收集所有重复的项(包括重复出现的每个实例) good_dups = [] for item in good: sorted_tuple = tuple(sorted(item)) if count_map[sorted_tuple] > 1: good_dups.append(sorted(item)) # 若想要原顺序的列表,替换成append(item) # 打印结果 print(f"There are: {len(good_dups)} duplicates among CORRECT lines:") for i, val in enumerate(good_dups): print('Duplicate', i+1, *val, sep=" ") print()
运行这段代码后,good_dups会包含3条记录(对应2,3,1、2,3,1、1,2,3排序后的结果),符合你的预期。
三、顺便修复wrong列表重复项的代码
你当前的wrong重复项代码完全写错了——循环的是good列表,统计的也是good的内容,这显然不对。修正后的代码类似:
# 统计wrong列表的重复项(按原列表完全匹配统计,若要忽略顺序可参考good的排序逻辑) wrong_count = {} for item in wrong: item_tuple = tuple(item) wrong_count[item_tuple] = wrong_count.get(item_tuple, 0) + 1 wrong_dups = [] for item in wrong: item_tuple = tuple(item) if wrong_count[item_tuple] > 1: wrong_dups.append(item) print(f"There are: {len(wrong_dups)} duplicates among ERROR lines:") for i, val in enumerate(wrong_dups): print('Duplicate', i+1, *val, sep=" ") print()
为什么你的原代码只返回2条?
你的原代码中,只有当good中存在完全和排序后x相同的原列表时才会被统计。比如两个['2','3','1']未排序列表,循环时x = sorted(x)变成['1','2','3'],但good.count(x)仅能匹配到原列表中的['1','2','3'](返回1),不会触发添加;但如果不排序直接用good.count(x),会统计到两个['2','3','1'],这时候会添加两次,所以你看到了2条结果。
内容的提问来源于stack exchange,提问作者frkfrk0

