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

如何为现有CSV文件新增Age列并根据DOB计算年龄?代码报错求助

问题描述

我有一个包含三列的CSV文件,列名分别为Name、DOB(格式为YYYY-MM-DD)、Salary,数据示例如下:

Name,DOB,Salary
Sam,2000-01-05,23000
Tyson,1989-09-11,29000
Lara,2002-11-19,19000
Brian,1990-04-20,21000
Tessa,2000-08-17,15000

需求说明:读取该文件并在终端展示数据,同时计算出每个人的年龄,新增名为'Age'的列,输出示例如下:

Name,DOB,Salary,Age
Sam,2000-01-05,23000,22
Tyson,1989-09-11,29000,51
Lara,2002-11-19,19000,20
Brian,1990-04-20,21000,32
Tessa,2000-08-17,15000,22

我编写了如下Python代码:

import csv
import datetime


def getage(now, dob):
    years = now.year - dob.year
    months = now.month - dob.month
    if now.day < dob.day:
        months -= 1
        while months < 0:
            months += 12
            years -= 1
    return '%sy%smo' % (years, months)


with open('emp_details.csv', 'r') as fin, open('emp_details_out.csv', 'w') as fout:
    csv_reader = csv.reader(fin)
    csv_writer = csv.writer(fout)

    for data in csv_reader:
        today = datetime.date.today()
        DOB = datetime.datetime.strptime(data["DOB"], "%Y-%m-%d").date()
        data["Age"] = getage(today, DOB)
        csv_writer.writerow(data)

但运行时出现如下错误:

DOB = datetime.datetime.strptime(data["DOB"], "%Y-%m-%d").date()
TypeError: list indices must be integers or slices, not str

我是CSV处理新手,急需帮助解决该问题。

错误原因分析

你使用csv.reader读取文件时,返回的每一行数据是列表类型,只能通过整数索引(比如data[1])访问列值,无法用字符串键(比如data["DOB"])直接定位列。另外你的getage函数返回的是22y0mo这类格式,和需求中的整数年龄不符,也需要调整。

修正方案

方法1:使用csv.DictReader和csv.DictWriter(推荐)

这种方法会将每行数据转为字典,直接用列名访问值,更贴合你原本的代码逻辑:

import csv
import datetime


def calculate_age(now, dob):
    # 计算整数年龄,匹配需求示例格式
    age = now.year - dob.year
    # 如果当前日期未到当年生日,年龄减1
    if (now.month, now.day) < (dob.month, dob.day):
        age -= 1
    return age


with open('emp_details.csv', 'r') as fin, open('emp_details_out.csv', 'w', newline='') as fout:
    # 自动识别表头作为字典键
    csv_reader = csv.DictReader(fin)
    # 定义输出列名,新增Age列
    fieldnames = csv_reader.fieldnames + ['Age']
    csv_writer = csv.DictWriter(fout, fieldnames=fieldnames)
    
    # 写入表头
    csv_writer.writeheader()
    # 打印表头到终端
    print(','.join(fieldnames))
    
    today = datetime.date.today()
    for row in csv_reader:
        # 解析DOB为日期对象
        dob = datetime.datetime.strptime(row['DOB'], "%Y-%m-%d").date()
        # 计算年龄并添加到字典
        row['Age'] = calculate_age(today, dob)
        # 写入文件
        csv_writer.writerow(row)
        # 在终端打印该行数据
        print(','.join([str(row[field]) for field in fieldnames]))

方法2:继续使用csv.reader(列表索引方式)

如果坚持用csv.reader,需要手动处理表头和数据行的索引对应:

import csv
import datetime


def calculate_age(now, dob):
    age = now.year - dob.year
    if (now.month, now.day) < (dob.month, dob.day):
        age -= 1
    return age


with open('emp_details.csv', 'r') as fin, open('emp_details_out.csv', 'w', newline='') as fout:
    csv_reader = csv.reader(fin)
    csv_writer = csv.writer(fout)
    
    # 读取并处理表头
    header = next(csv_reader)
    header.append('Age')
    csv_writer.writerow(header)
    print(','.join(header))
    
    # 获取DOB列的索引位置
    dob_index = header.index('DOB')
    today = datetime.date.today()
    
    for row in csv_reader:
        # 通过索引获取DOB值并解析
        dob_str = row[dob_index]
        dob = datetime.datetime.strptime(dob_str, "%Y-%m-%d").date()
        age = calculate_age(today, dob)
        # 添加年龄到行数据
        row.append(str(age))
        # 写入文件并打印到终端
        csv_writer.writerow(row)
        print(','.join(row))

内容的提问来源于stack exchange,提问作者Psyfer.Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:40:48