Linux下随机化文本文件行并确保无连续重复行
解决重复行随机化且无连续重复的方案
单纯用shuf、awk或perl的普通随机洗牌逻辑,只会做全随机排序,完全不考虑行内容的重复问题,所以必然会有概率出现连续重复行。要实现绝对避免相同行连续出现的随机化效果,可以用「频次统计+贪心随机选择」的思路来实现,以下是具体的Python实现方案:
核心逻辑
- 先统计文件中每行的出现次数,明确各内容的重复量级
- 每次选择行时,排除上一行的内容,优先从剩余次数最多的行中随机选一个(避免最后剩下大量重复行无法处理)
- 选完后对应行的剩余次数减1,直到所有行都被处理完毕
代码实现
import random from collections import defaultdict def shuffle_no_consecutive_duplicates(file_path): # 读取文件并统计每行出现频次 line_counts = defaultdict(int) with open(file_path, 'r', encoding='utf-8') as f: for line in f: line = line.rstrip('\n') line_counts[line] += 1 result = [] prev_line = None remaining = line_counts.copy() while sum(remaining.values()) > 0: # 筛选出和上一行不同且还有剩余次数的行 candidates = [line for line in remaining if remaining[line] > 0 and line != prev_line] # 极端情况:只剩一种行(数学上无法避免连续,比如总5行某行占3次) if not candidates: candidates = [line for line in remaining if remaining[line] > 0] # 优先选剩余次数最多的行,同频次的随机选 candidates.sort(key=lambda x: -remaining[x]) top_freq = remaining[candidates[0]] top_candidates = [line for line in candidates if remaining[line] == top_freq] chosen_line = random.choice(top_candidates) result.append(chosen_line) remaining[chosen_line] -= 1 prev_line = chosen_line # 将结果写入新文件 with open('shuffled_test.txt', 'w', encoding='utf-8') as f: f.write('\n'.join(result) + '\n') # 执行函数,传入目标文件路径 shuffle_no_consecutive_duplicates('test.txt')
方案特点
- 完全避免相同行连续出现(除非某行出现次数超过总行数的一半,这种极端场景数学上无法规避,业务数据中极少出现)
- 每次从高频候选行里随机选择,保证了整体序列的随机性,不是固定的机械排序
- 完整保留原文件的所有行,仅调整顺序
内容的提问来源于stack exchange,提问作者DarrenB
相关产品推荐
相关产品推荐

