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

Python CSV操作:执行writerows后能否直接修改并执行writerow?

CSV单函数内实现插入行与追加列的问题

我需要修改CSV文件,实现两个操作:插入指定行,同时为所有行追加用户选择的额外列(时间戳、文件名、唯一ID等)。但尝试时发现,执行output.writerows(rows)插入行后,后续循环处理追加列的逻辑完全失效;注释掉该语句后循环能正常运行,保留则会跳过写入的内容。

想请教:

  • 能否在单个函数内完成插入行+追加列的操作?
  • 是否必须先保存文件,重新打开后再追加列?

我的目标是让用户选择要追加的内容,最终将修改后的文件保存到新位置,已尝试多种方法一周仍未解决。

示例代码

import csv
import itertools
import uuid
from datetime import datetime

rows = [[1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2]]


def _sanitize_report(source_file, dest_file, append_timestamp, timestamp_format, append_filename, file,
                        append_id):
    with open(source_file, 'r') as report:
        reader = csv.reader(report)
        with open(dest_file, 'w') as output_file:
            data_rows = 0
            output = csv.writer(output_file)
            output.writerows(rows)
            for index, row in enumerate(reader):
                if append_timestamp and append_filename and append_id:
                    output.writerow(itertools.chain([datetime.today().strftime(timestamp_format)],
                                                    [str(file).replace(file[0:3], '')],
                                                    [uuid.uuid4()]))
                elif append_timestamp and append_filename:
                    output.writerow(itertools.chain([datetime.today().strftime(timestamp_format)],
                                                    [str(file).replace(file[0:3], '')]))
                elif append_timestamp and append_id:
                    output.writerow(itertools.chain([datetime.today().strftime(timestamp_format)], [uuid.uuid4()]))
                elif append_filename and append_id:
                    output.writerow(itertools.chain([str(file).replace(file[0:3], '')], [uuid.uuid4()]))
                elif append_timestamp:
                    output.writerow(itertools.chain( [datetime.today().strftime(timestamp_format)]))
                elif append_filename:
                    output.writerow(itertools.chain([str(file).replace(file[0:3], '')]))
                elif append_id:
                    output.writerow(itertools.chain([uuid.uuid4()]))
                else:
                    output.writerow([value.replace('(not set)', '') for value in row])
                data_rows += 1


_sanitize_report('test.csv', 'test_' + str(uuid.uuid4()) + '.csv',
                    append_timestamp=True, timestamp_format=datetime.utcnow().isoformat() + 'Z',
                    append_filename=True, file='123Test_success', append_id=True)

问题分析

你的代码逻辑存在两个核心问题:

  1. 写入逻辑错误:output.writerows(rows)写入自定义行后,后续循环遍历原文件的reader,执行output.writerow(...)是单独写入新行(而非给已写入的行追加列),这和你“追加额外列”的需求不符。
  2. 数据处理顺序混乱:你没有将插入的rows和原文件的行统一处理,而是分开写入,导致后续的追加逻辑无法作用到插入的行上。

解决方案:单函数内完成所有操作

完全不需要拆分操作,只需先统一处理所有数据(插入行+追加列),再一次性写入文件。修改后的代码如下:

import csv
import uuid
from datetime import datetime

rows = [[1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2],
        [1000000, 'Test', 'Test', 179, 1111, 222, 5, 'Test', 'Test', 1111, 'Test', 222, 'Test', 1111, 22222, 'Test', '', 1, 2]]


def _sanitize_report(source_file, dest_file, append_timestamp, timestamp_format, append_filename, file, append_id):
    # 1. 读取原文件所有行
    with open(source_file, 'r') as report:
        reader = csv.reader(report)
        original_rows = list(reader)
    
    # 2. 合并插入行与原文件行(可根据需求调整顺序,比如插在末尾或中间)
    all_rows = rows + original_rows
    
    # 3. 生成要追加的额外字段
    extra_fields = []
    if append_timestamp:
        extra_fields.append(datetime.today().strftime(timestamp_format))
    if append_filename:
        extra_fields.append(str(file).replace(file[0:3], ''))
    if append_id:
        extra_fields.append(str(uuid.uuid4()))
    
    # 4. 处理所有行:追加字段 + 清理内容
    processed_rows = []
    for row in all_rows:
        # 清理原内容中的'(not set)'
        cleaned_row = [value.replace('(not set)', '') for value in row]
        # 追加额外字段到行末尾
        cleaned_row.extend(extra_fields)
        processed_rows.append(cleaned_row)
    
    # 5. 一次性写入所有处理后的行
    with open(dest_file, 'w', newline='') as output_file:
        output = csv.writer(output_file)
        output.writerows(processed_rows)
    
    print(f"处理完成,共写入 {len(processed_rows)} 行")


_sanitize_report('test.csv', 'test_' + str(uuid.uuid4()) + '.csv',
                    append_timestamp=True, timestamp_format=datetime.utcnow().isoformat() + 'Z',
                    append_filename=True, file='123Test_success', append_id=True)

关键改进点

  1. 统一数据处理:先将插入的rows和原文件的行合并,再批量处理每一行,避免分阶段写入的逻辑混乱。
  2. 正确追加列:使用extend()将额外字段添加到每一行的末尾,真正实现“追加列”的效果。
  3. 简化逻辑:将生成额外字段的逻辑提前,避免重复的条件判断,代码更简洁易维护。
  4. 文件操作优化:只打开两次文件(一次读原文件,一次写新文件),避免嵌套文件操作的潜在问题。

补充说明

如果你需要将插入的行放在原文件行的中间或其他位置,只需调整all_rows = rows + original_rows这一行的拼接逻辑即可,比如all_rows = original_rows[:5] + rows + original_rows[5:]表示将插入行放在原文件第5行之后。

内容的提问来源于stack exchange,提问作者Maykid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:40:42