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

使用Python/Django提取CSV行时遇索引错误等问题求助

问题描述

我正尝试使用Python/Django提取CSV文件中的特定行,CSV内容格式如下:

POS,Transaction id,Product,Quantity,Customer,Date
1,E100,TV,1,Test Customer,2022-09-19
2,E100,Laptop,3,Test Customer,2022-09-20
3,E200,TV,1,Test Customer,2022-09-21
4,E300,Smartphone,2,Test Customer,2022-09-22
5,E300,Laptop,5,New Customer,2022-09-23
6,E300,TV,1,New Customer,2022-09-23
7,E400,TV,2,ABC,2022-09-24
8,E500,Smartwatch,4,ABC,2022-09-25

编写的代码如下:

def csv_upload_view(request):
    print('file is being uploaded')

    if request.method == 'POST':
        csv_file = request.FILES.get('file')
        obj = CSV.objects.create(file_name=csv_file)

        with open(obj.file_name.path, 'r') as f:
            reader = csv.reader(f)
            reader.__next__()
            for  row in reader:
                data = "".join(row)
                data = data.split(";")
                #data.pop()
                print(data[0], type(data))
                transaction_id = data[0]
                product = data[1]
                quantity = int(data[2])
                customer = data[3]
                date = parse_date(data[4])

控制台输出如下:

Quit the server with CONTROL-C.
[22/Sep/2022 15:16:28] "GET /reports/from-file/ HTTP/1.1" 200 11719
file is being uploaded
1E100TV1Test Customer2022-09-19 <class 'list'>

行内容被拼接在一起,若用空格join则行内容被空格分隔。我希望通过指定方式访问行数据,但总是出现IndexError: list index out of range。尝试用data.replace(" ",";"),又出现ValueError: invalid literal for int() with base 10: 'E',且数据类型变为字符串。请问我忽略了什么?

问题分析与解决

核心问题是你完全误用了csv.reader的工作逻辑,多做了画蛇添足的拼接和分割操作,具体问题点和修复方案如下:

  1. csv.reader已经帮你完成了行分割
    csv.reader读取CSV文件时,会自动按照逗号(CSV默认分隔符)把每行拆分成列表。比如第一行数据会直接被处理成['1', 'E100', 'TV', '1', 'Test Customer', '2022-09-19'],你不需要再用"".join(row)把它们拼起来——这直接破坏了已经分割好的结构,而你的CSV里根本没有分号,后续用split(";")自然只能得到一个元素的列表,访问data[1]、data[2]这类索引时必然报IndexError。

  2. 修复后的代码示例
    直接使用csv.reader返回的row列表即可,无需额外处理:

def csv_upload_view(request):
    print('file is being uploaded')

    if request.method == 'POST':
        csv_file = request.FILES.get('file')
        obj = CSV.objects.create(file_name=csv_file)

        with open(obj.file_name.path, 'r', encoding='utf-8') as f:
            reader = csv.reader(f)
            next(reader)  # 跳过表头,用next()比__next__()更符合Python规范
            for row in reader:
                # row已经是分割好的字段列表,直接按索引取值
                pos = row[0]
                transaction_id = row[1]
                product = row[2]
                quantity = int(row[3])
                customer = row[4]
                date = parse_date(row[5])
                # 这里可以添加保存到数据库等后续逻辑
                print(f"交易ID: {transaction_id}, 商品: {product}")
  1. 额外注意事项
  • 如果你的CSV文件用的不是逗号分隔符,需要在创建csv.reader时指定delimiter参数,比如csv.reader(f, delimiter=';'),但你的示例CSV用的是逗号,所以不需要。
  • 打开文件时建议指定编码(如utf-8),避免中文乱码问题。
  • next(reader)用于跳过表头行,这部分逻辑是对的,但用内置函数next()比直接调用reader.__next__()更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:05:39