以《哈利波特》人物为例,学用Python处理csv模块

Python 通过其内置模块提供的便利真的很有价值,对于 csv 模块也是如此。

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

您很有可能遇到或必须使用 CSV(逗号分隔值)文件。CSV 文件包含类似于电子表格的数据。它用 分隔符分隔 ,因此它不必总是逗号。但是,由于它是一个 逗号分隔值 文件,让我们看一个这样的示例:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin

如上例所示,第一行 ( first,last,house) 可用于标题作为列名。

Python方便地有一个内置的 csv模块以有效的方式处理 CSV 文件。两个基本操作是读和写;使用 Python,我们可以使用列表(或更一般地,任何可迭代的)或字典来执行这些操作。

csv.reader()

要读取 CSV 文件,一种选择是使用 csv.reader()方法。让我们看一个简单的例子 students.csv文件:

import csv

with open('students.csv') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        if row == ['first', 'last', 'house']:
            continue
        print(f'{row[0]} {row[1]} is in {row[2]}.')


# Harry Potter is in Gryffindor.
# Hermione Granger is in Gryffindor.
# Luna Lovegood is in Ravenclaw.
# Draco Malfoy is in Slytherin.

我们使用 context manager (https://docs.python.org/3/glossary.html#term-context-manager) 来打开我们的文件。(请注意,我们不需要指定 'r'参数作为读取操作的模式,因为它是默认值;请参阅 官方文档 (https://docs.python.org/3/library/functions.html#open) 。) 当我们使用 csv.reader(),它返回一个阅读器对象,我们将其存储在 reader多变的。然后,用一个 for循环,我们遍历每一行,这是一个列表——并且,因为我们的第一行实际上是标题,我们通过该迭代并继续。实际上, csv.DictReader()对此有更好的可用性,我们稍后会看到。这里重要的一点是每一行都是一个 list包含三个元素,我们通过索引访问它们( row[0]row[1]row[2])。这不是最优雅的实现,而是一个足够简单的例子来看看如何 csv.reader()作品。

csv.writer()

假设我们想将 Ron Weasley 添加到我们的 CSV 文件中,因为我们希望我们的黄金三重奏在一起。让我们看看我们如何去做:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['Ron', 'Weasley', 'Gryffindor'])

在这里,我们再次使用上下文管理器打开我们的 CSV 文件,这次使用 'a'参数作为附加到它的模式。之后,我们使用 csv.writer(),将我们的文件对象传递给它。它返回一个 writer 对象,我们将其存储在 writer变量。然后,我们调用 writerow()添加罗恩韦斯莱的方法。一个重要的事情是我们通过了一个 list作为一个论点,虽然它不一定是 list— 我们可以使用像元组这样的可迭代对象,但使用列表更为常见。

现在,我们的文件看起来像:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor

csv.DictReader()

我们可以改进上一个示例以读取 CSV 文件。让我们使用 csv.DictReader()这次:

import csv

with open('students.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(f'{row["first"]} {row["last"]} is in {row["house"]}.')


# Harry Potter is in Gryffindor.
# Hermione Granger is in Gryffindor.
# Luna Lovegood is in Ravenclaw.
# Draco Malfoy is in Slytherin.
# Ron Weasley is in Gryffindor.

像 csv.reader()csv.DictReader()返回一个阅读器对象,但这一次,正如文档所说,它“将每一行中的信息映射到 dict其键由可选的 fieldnames 参数给出。” 如果您已经意识到,我们没有指定 fieldnames 参数,所以第一行被用作默认字段名。我们可以通过查看 fieldnames我们的阅读器对象的属性:

import csv

with open('students.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    print(reader.fieldnames) # ['first', 'last', 'house']

csv.DictReader()绝对使代码比以前的方法更具可读性。让我们看看如何再次使用字典,这次是写入文件。

csv.DictWriter()

之前我们已将罗恩·韦斯莱添加到我们的 students.csv, 让我们这次再加一个韦斯莱,金妮。让我们看看如何用csv.DictWriter()来做。:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
    writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'house': 'Gryffindor'})

我们再次附加到我们的文件,就像我们做的那样 csv.writer(). 我们创建一个 writer 对象 csv.DictWriter(),当然将文件对象本身传递给它,然后将返回的写入器对象分配给变量 writer. 注意这里我们传递了一个名为 fieldnames同样,这是一个包含字段名的列表。它不是可选参数,因此我们每次使用时都必须提供它 csv.DictWriter(). 我们使用 writerow()再次调用方法,但这一次,我们向它传递了一个字典,其键是我们刚刚指定的字段名。现在我们的文件看起来像这样:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor

现在,如果在里面 writerow()你传入一个不在字段名中的键怎么办?显然,我们将有一个 ValueError,但让我们看一个例子。他们说房子不是家,但想象一下我们错误地将格兰芬多写成金妮的 home,而不是她 house正如我们在 fieldnames 。让我们来看看:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
    writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'home': 'Gryffindor'})


# ValueError: dict contains fields not in fieldnames: 'home'

这实际上来自可选 extrasaction里面的参数 csv.DictWriter(). 它的默认值为 'raise'中找不到键时 字段名 ,它会引发一个 ValueError. 但是,我们可以通过传递值来强制它忽略它 'ignore'. 所以,如果我们这样做:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'], extrasaction='ignore')
    writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'home': 'Gryffindor'})

在这种情况下,我们将完全忽略密钥,导致我们的文件如下所示:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,

不过,这不是最明智的决定,最好在这种情况下出错,除非我们有理由不这样做。

我们也可以使用 writerows()方法,通过写入多行。它需要一个可迭代的参数,所以假设我们在韦斯莱双胞胎的列表中有两个字典,我们可以同时添加它们:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
    twins = [
        {'first': 'Fred', 'last': 'Weasley', 'house': 'Gryffindor'},
        {'first': 'George', 'last': 'Weasley', 'house': 'Gryffindor'}
    ]
    writer.writerows(twins)

现在,我们的文件看起来像:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor

引用常量

尤其是在使用 writer 对象时,我们可能需要指定如何引用字段——例如,处理字段可能包含分隔符本身的情况。为此,我们可以使用可选的 quoting 方法的参数,以及 quotechar参数指定使用哪个字符作为引号。

这 csv模块有四个常量用于 quoting:

csv.QUOTE_ALL: 引用所有字段。csv.QUOTE_MINIMAL: 引用有特殊字符的字段(例如分隔符本身)。csv.QUOTE_NONNUMERIC: 引用所有非数字字段。csv.QUOTE_NONE: 从不引用字段。如果分隔符出现在其中一个字段中,则 escapechar使用字符。如果 escapechar未提供,它将引发错误。

让我们看一个简单的例子 csv.QUOTE_ALL使用 csv.DictWriter(). 可以想象,它将引用所有字段:

import csv

with open('students.csv', 'a') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'], quotechar='"', quoting=csv.QUOTE_ALL)
    writer.writerow({'first': 'Cho', 'last': 'Chang', 'house': 'Ravenclaw'})

现在,Cho Chang 的字段全部用引号引起来:

# 📁 students.csv

first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor
"Cho","Chang","Ravenclaw"

结论

Python 通过其内置模块提供的便利真的很有价值,对于 csv 模块也是如此。这篇文章探讨了读写 CSV 文件的非常简单的操作,但总有很多东西需要探索,而第一站总是官方文档(https://docs.python.org/3/library/csv.html)。希望你现在明白了处理CSV文件的一些基本知识。

编码愉快。

参考文章:https://dev.to/rivea0/csv-operations-101-with-pythons-own-csv-module-39b5

推荐书单

《Python从入门到精通》

https://item.jd.com/13284890.html

《Python从入门到精通(第2版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。全书共分23章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库、GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架、e起去旅行网站、AI图像识别工具等内容。所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。除此之外,该书还附配了243集高清教学微视频及PPT电子教案。

《Python从入门到精通(第2版)》可作为软件开发入门者的学习用书,也可作为高等院校相关专业的教学参考用书,还可供开发人员查阅、参考使用。

这本书有如下特色:

  • 循序渐进,实战讲述

  • 243集教学微课视频,39小时知识点精讲,可听可看,随时随地扫码学

  • 趣味解读,易教易学

  • 赠送Python实战训练背记手册

  • 在线解答,高效学习

    企业QQ、QQ群在线答疑,明日学院社区答疑。

    每周清大文森学堂在线直播答疑。

精彩回顾

Python是如何跑起来的?从字节码说起

【案例】如何使用Flask构建天气预报

手把手教你创建简单的Python Flask

微信搜素关注《Python学研大本营》

访问【IT今日热榜】,发现每日技术热点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值