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

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,,

问题原因

  1. 文件指针耗尽:第一次内层循环执行时,file2的读取指针已经移动到文件末尾,第二次外层循环执行row2 = file2.readline()时直接读到空字符串,内层循环无法触发。
  2. 未写入修改:代码仅修改了内存中的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:06:26