Python嵌套while循环异常:外层二次循环跳过内层循环求解
问题分析与解决
问题现象
对比两个CSV文件的ID,匹配时将b1的lon和lat复制到b2中。但代码首次循环正常,外层while第二次迭代时直接跳过内层while循环,且修改后的数据并未写入文件。
原代码
file1=open("b1.csv",mode='r',encoding='utf-8') file2=open("b2.csv",mode='r+',encoding='utf-8') header1 = file1.readline() header2 = file2.readline() row1 = file1.readline() while row1 != "": row2 = file2.readline() rowlist1 = row1.split(",") while row2 != "": rowlist2 = row2.split(',') if rowlist2[0] == rowlist1[0]: rowlist2[2] = rowlist1[2] rowlist2[3] = rowlist1[3] print(rowlist1,rowlist2) row2 = file2.readline() print(rowlist1) row1 = file1.readline()
文件内容
b1.csv
ID,name,lon,lat 1345,name1,123.6,20.3 5436,name2,123.7,25.6 5765,name3,212.3,21.2 3424,name4,154.5,23.3
b2.csv
ID,name,lon,lat 1345,name1,, 5436,name2,, 5765,name3,, 3424,name4,,
问题原因
- 文件指针耗尽:第一次内层循环执行时,
file2的读取指针已经移动到文件末尾,第二次外层循环执行row2 = file2.readline()时直接读到空字符串,内层循环无法触发。 - 未写入修改:代码仅修改了内存中的
rowlist2列表,并未将修改后的内容写回b2.csv,即使ID匹配成功,文件内容也不会更新。
修正方案
提供两种实现方式,分别适配中小文件和大文件场景:
方案1:内存批量处理(适合中小文件)
先将b1的坐标数据存入字典,再一次性读取b2内容修改后写回,代码简洁高效:
# 读取b1的ID与对应坐标,存入字典 with open("b1.csv", mode='r', encoding='utf-8') as f1: next(f1) # 跳过表头 id_coords = {} for line in f1: parts = line.strip().split(',') if len(parts) >= 4: id_coords[parts[0]] = (parts[2], parts[3]) # 读取b2所有内容并修改 with open("b2.csv", mode='r', encoding='utf-8') as f2: lines = f2.readlines() # 替换匹配ID的坐标 for i in range(1, len(lines)): # 从第二行开始处理数据行 parts = lines[i].strip().split(',') if parts[0] in id_coords: parts[2], parts[3] = id_coords[parts[0]] lines[i] = ','.join(parts) + '\n' # 将修改后的内容写回b2 with open("b2.csv", mode='w', encoding='utf-8') as f2: f2.writelines(lines)
方案2:逐行重置指针(适合大文件)
每次处理b1的一行前,重置file2的读取指针到表头后,逐行匹配并写入修改:
file1 = open("b1.csv", mode='r', encoding='utf-8') file2 = open("b2.csv", mode='r+', encoding='utf-8') header1 = file1.readline() header2 = file2.readline() header_bytes = len(header2.encode('utf-8')) # 计算表头字节长度,用于重置指针 row1 = file1.readline() while row1 != "": rowlist1 = row1.strip().split(",") # 重置file2指针到表头之后的位置 file2.seek(header_bytes) row2 = file2.readline() while row2 != "": rowlist2 = row2.strip().split(',') if rowlist2[0] == rowlist1[0]: # 定位当前行起始位置,写入修改后的内容 current_pos = file2.tell() - len(row2.encode('utf-8')) rowlist2[2] = rowlist1[2] rowlist2[3] = rowlist1[3] new_line = ','.join(rowlist2) + '\n' file2.seek(current_pos) file2.write(new_line) row2 = file2.readline() row1 = file1.readline() file1.close() file2.close()
内容的提问来源于stack exchange,提问作者Ganyu Simp
相关产品推荐
相关产品推荐

