Python实现类Linux diff格式输出嵌套列表的问题排查与优化
问题描述
我是Python新手,需要将结构为[[操作符, 文件1行号, 文件2行号]]的嵌套列表,按照Linux diff命令的格式输出:
- 单个操作实例输出如
4c5; - 若存在连续相同操作的实例,则合并为一行输出(例如
[['c',4,5],['c',6,7],['c',7,8],['d',9,10]]应输出4,6,7c5,7,8和9d10)。
我尝试了一段代码,但输出存在问题:使用set导致行号顺序错乱、最后两个c操作未显示、输出格式不符合预期,现需排查代码问题并提供更优实现方案。
原尝试代码
dist=[['d', 1, 0], ['d', 2, 0], ['c', 5, 4], ['a', 7, 7], ['a', 7, 8], ['d', 10, 10], ['d', 13, 12], ['c', 14, 13], ['c', 15, 14]] op=[] line1=[] line2=[] for rows in range(len(dist)): if (rows==0 and dist[rows][0]==dist[rows+1][0])or(dist[rows][0]==dist[rows-1][0]) : op.append(dist[rows][0]) line1.append(dist[rows][1]) line2.append(dist[rows][2]) if dist[rows][0]!=dist[rows+1][0]: print(set(line1),set(op),set(line2)) op.clear() line1.clear() line2.clear() elif dist[rows][0]==dist[rows+1][0]: op.append(dist[rows][0]) line1.append(dist[rows][1]) line2.append(dist[rows][2]) if dist[rows][0]!=dist[rows+1][0]: print(set(line1),set(op),set(line2)) op.clear() line1.clear() line2.clear() else: print(f'{dist[rows][1]}{dist[rows][0]}{dist[rows][2]}')
错误输出
{1, 2} {'d'} {0} # 用set去重但打乱了行号顺序 5c4 {7} {'a'} {8, 7} # set反转了数字顺序 {10, 13} {'d'} {10, 12} # 最后两个'c'操作完全未显示
原代码问题分析
- set导致行号乱序:set是无序集合,会打乱原本的行号顺序,且diff需要保留连续操作的行号原始顺序(重复行号是合理场景),不能去重。
- 边界处理错误:循环到最后一个元素时,
dist[rows+1]会触发索引越界,导致最后两个连续的c操作未被处理。 - 逻辑冗余重复:两个if分支逻辑几乎完全重复,且连续操作的判断逻辑不清晰,未正确跟踪当前操作组。
- 输出格式不符:diff要求格式为
行号列表+操作符+行号列表,原代码输出集合格式完全不符合要求。
优化实现方案
优化代码
def format_diff(diff_list): if not diff_list: return # 初始化当前操作组 current_op = diff_list[0][0] file1_lines = [diff_list[0][1]] file2_lines = [diff_list[0][2]] for item in diff_list[1:]: op, line1, line2 = item if op == current_op: # 同一操作,追加行号到当前组 file1_lines.append(line1) file2_lines.append(line2) else: # 不同操作,输出当前组并重置 print(f"{','.join(map(str, file1_lines))}{current_op}{','.join(map(str, file2_lines))}") current_op = op file1_lines = [line1] file2_lines = [line2] # 输出最后一组未处理的操作 print(f"{','.join(map(str, file1_lines))}{current_op}{','.join(map(str, file2_lines))}") # 测试输入 dist = [['d', 1, 0], ['d', 2, 0], ['c', 5, 4], ['a', 7, 7], ['a', 7, 8], ['d', 10, 10], ['d', 13, 12], ['c', 14, 13], ['c', 15, 14]] format_diff(dist)
代码说明
- 分组逻辑:遍历列表时跟踪当前操作符,将连续相同操作的行号收集到对应列表中。
- 输出处理:遇到不同操作符时,将收集到的行号用逗号连接,按diff格式输出;遍历结束后单独处理最后一组操作,避免边界遗漏。
- 顺序保留:用列表存储行号,完全保留原始顺序,无乱序问题。
- 简洁高效:逻辑清晰无冗余,避免索引越界问题。
测试输出
1,2d0 5c4 7,7a7,8 10,13d10,12 14,15c13,14
内容的提问来源于stack exchange,提问作者Scarredowl
相关产品推荐
相关产品推荐

