csv文件

作者: 若晴y | 来源:发表于2021-04-12 15:51 被阅读0次

    读取csv文件内容
    csv文件的概念

    这应该是你第一次接触csv这种格式的文件吧。那么什么是csv文件呢?

    csv是"Comma-Separated Values(逗号分割的值)"的首字母缩写,它其实和txt文件一样,都是纯文本文件。但csv文件可以显示为电子表格的样式,所以我们也可以把csv文件视为一种简化版的电子表格。

    简化版是什么意思呢?回顾一下我们常见的Excel表格,不仅有“居中”排版,表格边框等样式,还有各种Excel公式等其他功能,这些功能在csv文件中是不存在的。

    正如概念中强调的一样,csv文件是纯文本文件,它只能存储数据。

    值得注意的是,csv文件有多种打开方式,如果你使用文本编译器(如记事本)打开它,它就会以文本形式显示;但如果你使用常用的office软件(Excel表格,WPS表格,Numbers表格)打开,csv就会直接显示为表格样式。
    下面的图片中,就是对同一份csv文件的不同显示方式,希望你能注意到文本形式中的逗号,每一个逗号都将数据分隔开来,就像表格里的边框分开不同的数据一样。


    image.png

    如果只是记录数据,不对数据进行操作的话,相较于Excel表格,csv文件会更加简洁轻便。

    使用Python来读写csv文件是非常容易的,因为实现csv的读取和写入功能的csv模块,是一个内置模块,我们可以直接使用。

    当然,使用csv模块时,需要先导入它,即在代码一开始写入import csv。

    打开csv文件
    了解了什么是csv文件后,接下来就是要用Python来打开它。使用的函数你也很熟悉——open()。

    是的,函数open()不仅可以打开txt文本文件,它也可以用来打开csv文件。使用open()打开的文件,都会返回一个文件对象。

    与打开txt文本文件稍有不同的地方是,我们需要在open()中传入新的参数newline=''。根据Python官方文档的相关规定,当我们打开csv文件时,需要设置参数newline='',这样可以避免一些不必要的空行。

    会产生空行的原因涉及了不同计算机系统的设计标准,这些问题比较深奥,你现在不必了解,只要记得Python官方推荐这么写就可以了。

    更好的文件打开方式

    你应该记得,我一直在强调:所有打开的文件对象,都应该被关闭。即使用open()打开文件时,在最后都需要使用方法文件对象.close()来关闭打开的文件。

    但是,人难免有疏忽的时候。如果不使用该方法,不仅是一种较差的编程习惯,还可能会产生一些异常。

    为了避免你出现忘记写close()的情况发生,同时也为了不让程序发生一些意料之外的异常,我要介绍一种不写文件对象.close()的方法,一种更好地打开文件的方法:

    with open() as …

    with open() as ...是对原有open()和close()的优化。

    使用with open() as ...语句后,在with下面的代码块结束时,会自动执行close()关闭文件。

    用法是把open()函数放在with后面,把变量名放在as后面,结束时要加冒号:,然后把要执行的文件处理语句缩进到with open() as ...下方的代码块中。

    具体语法你可以参考下图:


    image.png

    需要特别强调的是,在传统方法中,我们将open()返回的文件对象以变量= open ()的形式赋值给了变量。但在with...as...中时,我们没有使用变量 =的形式,而是直接将变量放在了as后面,如下图所示。


    image.png
    请务必记住缩进,打开文件之后的其他文件操作,都应该位于with下缩进的代码块中。

    读取csv文件内容
    现在开讲本节课的重头戏 —— 读取csv文件内容。

    如果你回看代码的话,你会发现我在代码中使用了DictReader。其实csv模块内置了两种读取csv文件的方式:函数reader()和类DictReader,为了确保知识的完整性,让你对csv模块有更加全面的认识,我会先从最基本的reader()函数讲起。

    reader()函数是csv模块内的一个函数,当使用open()打开csv文件,得到文件对象后,可以把这个文件对象传入reader()函数。

    官方文档中的语法可参考下图,不过你只需要记住框出来的参数就好,其他参数目前用不到,不用刻意地去记忆。


    image.png

    reader()函数会返回一个reader对象,这是一个可迭代对象,该对象里面的每一个元素都是一个列表,每一个列表都对应了csv文件中的一行。

    因此,通过遍历,我们可以读取csv文件中的每一行。

    下面来练习一道题。

    请你根据注释提示,使用reader()读取一个csv文件(reader_demo.csv),并使用for循环来打印csv文件中的每一行内容。
    import csv# 导入csv模块
    path='./reader_demo.csv'
    with open(path, 'r', encoding='utf-8', newline='') as source_file:

    使用with open() as 打开'./reader_demo.csv',注意设置必要的参数

     file_csv=csv.reader(source_file)    
    # 将文件对象转换为reader对象
     for row in file_csv:
    # 循环遍历reader对象,
         print(row)
        # 打印csv文件中的每一行内容
    

    csv文件以文本形式显示和在终端的输出对比图如下:

    image.png

    讲完了函数reader(),下面来讲我们代码中使用的DictReader类。(reader()是函数,DictReader是类,注意区分。)

    他们二者有什么区别呢?什么时候应该使用reader(),什么时候用DictReader呢?

    如果在csv文件中存在映射关系(即csv文件的第一行为表格中的表头),如图所示:


    image.png

    这样的csv文件当然可以使用reader()函数来读取,但是csv模块为我们提供了一种更好的读取方式——DictReader类,使用这个类来读取第一行为表头的csv文件,可以更好地反映出表头与文件内容的映射关系。

    那么,DictReader到底是什么呢?相关代码应该怎么写呢?我们先来看看Python官方文档中的写法。


    image.png

    和之前一样,你只需要记住框起来的参数就好,其他参数目前用不到,不用刻意地去记忆。

    DictReader类的操作类似于常规的reader(),但DictReader会将读取到的信息转换为字典形式。

    实例化DictReader类后,会得到一个DictReader对象,这是一个可迭代对象,我们可以使用循环来遍历它的每一个元素。但不同于reader()的是,该对象里面的每一个元素都是一个字典,每一个字典的值都可以对应csv文件中的一行,键对应csv文件的表头。

    这个类还有个属性fieldnames,该属性可以将csv文件(表格)的表头(第一行)读取出来,返回值是列表。这个表头也就是字典的键(key)。
    从输出结果可以看到,通过fieldnames取得表头是列表形式的。for循环遍历DictReader后,打印了除表头外的所有内容,其中的每一个元素都是字典,字典的键就是表头。如图所示。

    image.png
    1. 内容写入新的csv文件
      按照项目要求,我们需要将【员工发展基金确认表.csv】拆分为若干个以【xxx.csv】(xxx代表员工姓名)命名的文件,并且将相应的内容写入各个【xxx.csv】中。

    如何拆分呢?

    首先,需要通过for循环遍历DictReader对象,从csv文件中获取除表头外的所有内容。

    接着,使用字典取值和字符串拼接的相关知识,得到要写入内容的csv文件的路径,从而创建这个文件。

    最后,将每一行内容写入相应的新csv文件中。

    这就是拆分的思路,其实也是这个功能块的一个整体思路。我们将按照这个顺序来学习。

    创建新的csv文件
    在刚才读取csv文件内容代码的最后部分,我们已经通过for循环遍历出了csv文件中除表头外的每一行数据。

    接下来要做的,可以分为两步:一、获取【xxx.csv】(xxx代表员工姓名)的完整路径;二、创建这个文件。

    获取完整的文件路径

    回看一下刚才的代码。

    导入csv模块

    import csv

    设置员工发展基金确认表路径

    source_path = './员工发展基金确认表.csv'

    打开员工发展基金确认表

    with open(source_path, 'r', encoding='utf-8', newline='') as source_file:
    # 将文件对象转换成DictReader对象
    source_csv = csv.DictReader(source_file)
    # 将csv文件的表头读取出来
    headers = source_csv.fieldnames
    # 循环打印除表头以外的所有数据
    for csv_row in source_csv:
    # 打印数据
    print(csv_row)

    通过刚才的学习可知,source_csv的每一元素都是一个字典,我们可以通过字典的键来取出对应的值。

    所以需要做的就是取出键为'姓名'的对应值,并拼接文件名后缀'.csv',得到格式为'姓名.csv'的文件名。

    根据获取的员工名字拼接新文件名

    file_name = csv_row['姓名'] + '.csv'
    得到文件名后,将其和存放拆分结果文件的文件夹路径'./员工发展基金/'进行拼接,进而获得完整的文件路径。

    拼接新文件路径

    file_path = result_path + file_name
    创建文件对象

    获取到完整的文件路径后,就可以创建要写入的文件了。

    用刚刚学过的with open () as来写会很简单。向open()的参数path传递完整的文件路径,因为我们需要将内容写到文件中,因此需要将参数mode设置为写模式,即'w'。

    然后,按照公司惯例,继续将编码参数encoding设置为'utf-8',最后要按照Python官方文档的要求,写入参数newline=''。

    根据获取的员工名字拼接新文件名

    file_name = row['姓名'] + '.csv'

    拼接新文件路径

    file_path = result_path + file_name

    创建新文件并添加数据

    with open(file_path, 'w', encoding='utf-8', newline='') as target_file:

    写入内容

    与读取功能类似,csv模块也为我们准备了两种写入方式——函数writer()与类DictWriter。为了确保知识的完整性,我要先讲writer(),然后再讲代码会用到的DictWriter

    writer()函数是csv模块内的一个函数,当使用open()打开csv文件,得到文件对象后,可以把这个文件对象传入writer()函数。

    官方文档中的语法可参考下图,你也只需要记住图中框出来的参数就好,其他参数目前用不到,不用刻意地去记忆。

    image

    writer()函数会返回一个writer对象,可以调用该对象的方法将字符串文本写入csv文件。

    具体要如何做呢?

    要将内容写入csv文件,需要先把open()返回的文件对象转化为writer对象。

    然后需要调用writer对象的方法writerow(row),该方法会将参数row当作一行内容写入csv文件中
    参数row代表了你想要写入csv文件的内容,它必须是一个可迭代对象,这里推荐使用列表。

    另外,如果你想通过这个方法写入多行数据。需要借助循环来实现。

    下面来练道题,加强你对这部分知识的应用能力

    import csv
    member_list = [
    ['邱大仁'],
    ['徐小刚', '陈知枫'],
    ['王晴', '廖雨']
    ]

    打开并创建'./writerows_demo.csv'文件,注意参数的设置,获取文件对象

    with open('./writerows_demo.csv', 'w', encoding='utf-8', newline='') as demo_file:
    # 将文件对象转换为writer对象
    csv_demo = csv.writer(demo_file)
    # 将列表中的元素写入csv文件中
    csv_demo.writerows(member_list)

    DictWriter类

    讲完了函数writer(),现在来说说我在任务代码中使用的DictWriter类。(writer()是函数,DictWriter是类,注意区分。)

    从名字上就可以看出来,DictWriter是可以和刚才讲过的DictReader对应起来的。

    先来看看Python官方文档中的写法。老规矩,只看下图被框住的参数就好。


    image.png

    DictWriter的操作类似于常规的writer(),但DictWriter会将字典写入(映射)到csv文件的行中。

    即通过DictWriter写入的行,都必须是字典形式,这点和writer()还是有区别的。

    所以,当我们需要将字典类型的数据写入csv文件时,使用DictWriter会是一种更好的选择。

    有一点需要你特别注意,与DictReader不同,在上面的图片中,我特意标注出了一个参数fieldnames。

    在实例化DictWriter时,必须要传入该参数。

    我们需要将一个列表传给参数fieldnames,它的作用是设置csv文件的第一行数据(即表头数据)。当我们要将字典通过DictWriter对象写入csv文件时,通常会把字典的键(key)存入一个列表,再把这个列表传给参数fieldnames。

    结合图片来理解一下。


    image.png

    实例化DictWriter后,会得到一个DictWriter对象,我们需要通过该对象来调用两个方法来写入内容。

    第一个方法:writeheader(),该方法可将表头(即字典中的键(key))写入csv的第一行。

    也就是说,如果要写入表头,不仅要在DictWriter中传入参数fieldnames,还需要调用writeheader()方法。这点很重要,一定要记住。

    第二个方法:writerow(row),与writer对象调用writerow(row)不同的是,这里的参数row必须是字典形式的数据。

    在写入时,该方法会根据字典的键,找到相应的表头,然后再将此键对应的值写入表头对应的列。


    image.png

    相关文章

      网友评论

          本文标题:csv文件

          本文链接:https://www.haomeiwen.com/subject/auzikltx.html