Python CSV Reader/Writer 例子--转载
CSV(comma-separated values) 是跨多种形式导入导出数据的标准格式,比如 MySQL、Excel。
它以纯文本存储数和文本。文件的每一行就代表一条数据,每条记录包含了由逗号分隔的一个或多个属性值。这个标准格式的名字来源就是每条记录是用逗号将其属性分隔的。
即使有这个非常明显的命名标准,而实际上却没有一个官方的标准 CSV 格式,有可能是以一些比较类似的分隔符来分隔数据,虽然它们的扩展是 .csv 但是实际上却用了各种符号,空格、tab,这些也是比较流行的符号。有时由于缺少严格的定义使得数据移植变得很困难。
RFC 4180 提供了一些标准:
- 内容为纯文本
- 包含记录
- 每条记录是用单个分隔字符将各属性分隔
- 每条记录的属性序列是相同的
除非提供的 CSV 文件有额外的说明信息(比如使用 RFC 提供的标准),否则处理这种数据格式将是相当烦人的。
1.基础
Python 天生支持读取 CSV 格式数据并且是可配置的(这个我们看到是必不可少的)。在 Python 里边有个模块 csv ,它包含了 CSV 读取/生成所需的所有支持,并且它遵守 RFC 标准(除非你覆盖了相应的配置),因此默认情况下它是能够读取和生成合法的 CSV 文件。
那么,我们看看它是如何工作的:
- import csv
- with open('my.csv', 'r+', newline='') as csv_file:
- reader = csv.reader(csv_file)
- for row in reader:
- print(str(row))
代码中我们导入了 csv 模块并且打开了 "my.csv" 文件,将文件作为参数传给 csv.reader,调用这个方法后我们将 reader 里边的每行数据输出。
假设 'my.csv' 里边的内容为:
- my first column,my second column,my third column
- my first column 2,my second column 2,my third column 2
那么我们运行这个代码后,相应的输出:
- ['my first column', 'my second column', 'my third column']
- ['my first column 2', 'my second column 2', 'my third column 2']
生成和读取一样的简单:
- import csv
- rows = [['1', '2', '3'], ['4', '5', '6']]
- with open('my.csv', 'w+', newline='') as csv_file:
- writer = csv.writer(csv_file)
- for row in rows:
- writer.writerow(row)
- with open('my.csv', 'r+', newline='') as csv_file:
- reader = csv.reader(csv_file)
- for row in reader:
- print(str(row))
在 csv 文件的数据会是:
- 1,2,3
- 4,5,6
输出的内容:
- ['1', '2', '3']
- ['4', '5', '6']
到这里我们都非常清楚代码逻辑。我们将文件作为参数给 writer,以写模式打开,然后用它来写每一行数据。下边是更灵活的方式:
- import csv
- def read(file_location):
- with open(file_location, 'r+', newline='') as csv_file:
- reader = csv.reader(csv_file)
- return [row for row in reader]
- def write(file_location, rows):
- with open(file_location, 'w+', newline='') as csv_file:
- writer = csv.writer(csv_file)
- for row in rows:
- writer.writerow(row)
- def raw_test():
- columns = int(input("How many columns do you want to write? "))
- input_rows = []
- keep_going = True
- while keep_going:
- input_rows.append([input("column {}: ".format(i + 1)) for i in range(0, columns)])
- ui_keep_going = input("continue? (y/N): ")
- if ui_keep_going != "y":
- keep_going = False
- print(str(input_rows))
- write('raw.csv', input_rows)
- written_value = read('raw.csv')
- print(str(written_value))
- raw_test()
我们询问用户每行需要的列数然后是否继续输入下一行,随后我们输出读入的一般数据并且将这些内容生成到一个叫 raw.csv,然后继续这样一个过程。当我们运行这个程序,相关的内容如下:
- How many columns do you want to write? 3
- column 1: row 1, column 1
- column 2: row 1, column 2
- column 3: row 1, column 3
- continue? (y/N): y
- column 1: row 2, column 1
- column 2: row 2, column 2
- column 3: row 3, column 3
- continue? (y/N):
- [['row 1, column 1', 'row 1, column 2', 'row 1, column 3'], ['row 2, column 1', 'row 2, column 2', 'row 3, column 3']]
- [['row 1, column 1', 'row 1, column 2', 'row 1, column 3'], ['row 2, column 1', 'row 2, column 2', 'row 3, column 3']]
- Process finished with exit code 0
当然我们的 raw.csv 内容是:
- "row 1, column 1","row 1, column 2","row 1, column 3"
- "row 2, column 1","row 2, column 2","row 3, column 3"
CSV 格式的另一个规则就是引号。在上边的例子中,每一个输入都包含一个逗号,而逗号是我们的分隔符,所以这个逗号被放到了引号(标准的默认值)中间表示在此间的并非分隔符而只是每列中的符号而已。
虽让我推荐保留标准的配置信息,不过也存在一些情况需要更改默认配置,毕竟你没法控制的数据提供方给出的 csv 文件。因此,我不得不教你如何调整配置(beware, 责任越大权力越大)。
你能够通过设置 delimiter 和 quotechar 来配置分隔符和引用符:
- import csv
- def read(file_location):
- with open(file_location, 'r+', newline='') as csv_file:
- reader = csv.reader(csv_file, delimiter=' ', quotechar='|')
- return [row for row in reader]
- def write(file_location, rows):
- with open(file_location, 'w+', newline='') as csv_file:
- writer = csv.writer(csv_file, delimiter=' ', quotechar='|')
- for row in rows:
- writer.writerow(row)
- def raw_test():
- columns = int(input("How many columns do you want to write? "))
- input_rows = []
- keep_going = True
- while keep_going:
- input_rows.append([input("column {}: ".format(i + 1)) for i in range(0, columns)])
- ui_keep_going = input("continue? (y/N): ")
- if ui_keep_going != "y":
- keep_going = False
- print(str(input_rows))
- write('raw.csv', input_rows)
- written_value = read('raw.csv')
- print(str(written_value))
- raw_test()
现在我们的输出值为:
- How many columns do you want to write? 3
- column 1: row 1 column 1
- column 2: row 1 column 2
- column 3: row 1 column 3
- continue? (y/N): y
- column 1: row 2 column 1
- column 2: row 2 column 2
- column 3: row 2 column 3
- continue? (y/N):
- [['row 1 column 1', 'row 1 column 2', 'row 1 column 3'], ['row 2 column 1', 'row 2 column 2', 'row 2 column 3']]
- [['row 1 column 1', 'row 1 column 2', 'row 1 column 3'], ['row 2 column 1', 'row 2 column 2', 'row 2 column 3']]
我们的 raw.csv 文件中结果是:
- |row 1 column 1| |row 1 column 2| |row 1 column 3|
- |row 2 column 1| |row 2 column 2| |row 2 column 3|
我们可以看到,新分隔符已经变成了空格,而我们的引用符变成了管道,这主要是空格在每个文本数据中都有包含,因此 writer 强制使用管道来划分。
writer 的引用策略同样是可配置的,能够用的参数如下:
- csv.QUOTE_ALL: 把每列都扩起来,无论是否包含分隔符
- csv.QUOTE_MINIMAL: 只将包含分隔符的列扩起来
- csv.QUOTE_NONNUMBERIC: 将所有非数值的列扩起来
- csv.QUOTE_NONE: 不扩起来。这种方式强制用户检查每列的输入中是否包含分隔符,如果不检测,读取的列数将会是错误的。
读/写字点数据
我们已经看过了一些基础的读取/生成 CSV 数据的例子,不过在实际环境中,我们并不希望 CSV 文件那么的混乱,我们需要它们给出里边每一个列所表示的意义。
同样,实际环境下我们的数据不一定都是在数组中,我们有的是一些业务模型并且易懂。通常我们会使用字典来达到这个目的,python 相应提供了从 CVS 中读取/生成字典的工具。
代码差不多这个样子:
- import csv
- dictionaries = [{'age': '30', 'name': 'John', 'last_name': 'Doe'}, {'age': '30', 'name': 'Jane', 'last_name': 'Doe'}]
- with open('my.csv', 'w+') as csv_file:
- headers = [k for k in dictionaries[0]]
- writer = csv.DictWriter(csv_file, fieldnames=headers)
- writer.writeheader()
- for dictionary in dictionaries:
- writer.writerow(dictionary)
- with open('my.csv', 'r+') as csv_file:
- reader = csv.DictReader(csv_file)
- print(str([row for row in reader]))
我们用一个数组的测试数据初始化 dictionaries 变量,然后我们打开一个 write 模式的文件,将字典数据中的键集合写入到文件中。首先我们做的就是写键集合,然后再写数组中的字典,一个字典一行。
接下来我们以 read 模式打开同一个文件,获取此文件的 reader,然后将其打印成数组。输出结果如下:
- [{'name': 'John', 'age': '30', 'last_name': 'Doe'}, {'name': 'Jane', 'age': '30', 'last_name': 'Doe'}]
输出的 CSV 文件如下:
- name,last_name,age
- John,Doe,30
- Jane,Doe,30
现在它看起来就舒服多了。这个 CSV 文件包含了列信息,每行按照列顺序将数据排列好。注意到我们把属性名字给了 writer,在 python 中字典是无序的,因此在给定的情况下每行的数据顺序将会是之前所指定的。
这种方法同样可以应用到配置了分隔符和引用符的默认 writer 和 reader 上。
同样,我们把代码变的更灵活些:
- import csv
- def read_dict(file_location):
- with open(file_location, 'r+') as csv_file:
- reader = csv.DictReader(csv_file)
- print(str([row for row in reader]))
- return [row for row in reader]
- def write_dict(file_location, dictionaries):
- with open(file_location, 'w+') as csv_file:
- headers = [k for k in dictionaries[0]]
- writer = csv.DictWriter(csv_file, fieldnames=headers)
- writer.writeheader()
- for dictionary in dictionaries:
- writer.writerow(dictionary)
- def dict_test():
- input_rows = []
- keep_going = True
- while keep_going:
- name = input("Name: ")
- last_name = input("Last Name: ")
- age = input("Age: ")
- input_rows.append({"name": name, "last_name": last_name, "age": age})
- ui_keep_going = input("continue? (y/N): ")
- if ui_keep_going != "y":
- keep_going = False
- print(str(input_rows))
- write_dict('dict.csv', input_rows)
- written_value = read_dict('dict.csv')
- print(str(written_value))
- dict_test()
我们现在运行这个代码,会有如下的结果:
Name: John
Last Name: Doe
Age: 30
continue? (y/N): y
Name: Jane
Last Name: Doe
Age: 40
continue? (y/N):
[{'age': '30', 'last_name': 'Doe', 'name': 'John'}, {'age': '40', 'last_name': 'Doe', 'name': 'Jane'}]
[{'age': '30', 'last_name': 'Doe', 'name': 'John'}, {'age': '40', 'last_name': 'Doe', 'name': 'Jane'}]
我们的 dict.csv 内容:
age,last_name,name
30,Doe,John
40,Doe,Jane
一些注意点。就像我之前说过的,在 python 中字典是无序的,所以当你从一个字典中提取键集合并将数据写入到一个 CSV 文件的时候你应该将它们排好序始终使它们保持同样的顺序。你并不知道你的用户会用什么方法来读取这些数据,当然,在实际环境中 CSV 文件总是在增长的,你总是在增加文件的行,而不是覆盖它们。为了避免不必要的麻烦首先就是确保你的 CSV 文件始终看起来相同。
Python CSV Reader/Writer 例子--转载的更多相关文章
- python csv.reader参数指定
- python 使用csv.reader和csv.writer读写文件并转换成dataframe格式
import csv import pandas as pd ###csv.reader用法 ''' f=open(r"C:\Users\admin\pycdtest\wanyue\yuee ...
- python csv模块的reader是一个迭代器,无法多次迭代
在一个项目中,我需要多次遍历一个文本,该文本我是用csv.reader读取的.但后来发现,本文只对第一次循环有用,而之后的循环均为空白.经过排错后,我确定问题就出现在csv.reader()这一步.之 ...
- Python CSV文件处理/读写及With as 用法
可以不使用CSV模块 逐行处理: for line in open("samples/sample.csv"): title, year, director = line.spli ...
- Python csv.md
csv csv模块可以用于处理从电子表格和数据库导出的数据到带有字段和记录格式的文本文件,通常称为逗号分隔值(csv)格式,因为逗号通常用于分隔记录中的字段. Reading csv.reader(c ...
- Python CSV模块简介
Table of Contents 1. CSV 1.1. 简介 1.2. 字典方式地读写 1.3. 其它 2. 参考资料 CSV csv文件格式是一种通用的电子表格和数据库导入导出格式.最近我调用R ...
- Python CSV模块处理文件读写
下面是一个简单的csv文件 Title,Release Date,Director And Now For Something Completely Different,1971,Ian MacNau ...
- Python CSV 超简明用法
平常经常会用CSV存储数据,不可避免的会跟CSV文件的读写操作扯上关系. Python有CSV这个Package来解决这个问题,官网也有比较详细的教程 https://docs.python.org/ ...
- Python csv模块的使用
1.csv简介 CSV (Comma Separated Values),即逗号分隔值(也称字符分隔值,因为分隔符可以不是逗号),是一种常用的文本 格式,用以存储表格数据,包括数字或者字符.很多程序在 ...
随机推荐
- Gson的两种解析用法
第一种. 常见的解析,直接将json字符串解析为对应的类. public JavaBean getJsonString(String jsonString) { Gson gson = new Gso ...
- FDR错误发现率-P值校正学习[转载]
转自:https://baike.baidu.com/item/FDR/16312044?fr=aladdin https://blog.csdn.net/taojiea1014/article/d ...
- 软件包管理:rpm命令管理-校验和文件提取
校验主要用于判断文件是否做了更改 修改标志: 会用-V,会看输出结果即可. 当有误操作,比如删了某一个文件,只需知道他属于哪一个rpm包,可用提取找回覆盖就行.并不把整个rpm包安装,而是提取其中的某 ...
- SSH无密码登录:只需两个简单步骤 (Linux)
最后更新 2017年4月8日 分类 最新文章 服务器安全 标签 RSA SSH Key 非对称加密 如果你管理一台Linux服务器,那么你就会知道每次SSH登录时或者使用scp复制文件时都要输入密码是 ...
- SQL Server查询中特殊字符的处理方法
SQL Server查询中,经常会遇到一些特殊字符,比如单引号“'”等,这些字符的处理方法,是SQL Server用户都应该需要知道的. 我们都知道SQL Server查询过程中,单引号“'”是特殊字 ...
- python练习-生成一个1到50的大字符串每个数字之间有个空格
#-*-encoding:UTF-8-*- string=[] for i in range(1,51): string.append(str(i)) print string#打印一下string ...
- 44 道 JavaScript 难题
JavaScript Puzzlers原文 1. ["1", "2", "3"].map(parseInt) 答案:[1, NaN, N ...
- Vlock用于有多个用户访问控制台的共享 Linux 系统
当你在共享的系统上工作时,你可能不希望其他用户偷窥你的控制台中看你在做什么.如果是这样,我知道有个简单的技巧来锁定自己的会话,同时仍然允许其他用户在其他虚拟控制台上使用该系统. 要感谢Vlock(Vi ...
- MySQL数据库----IDE工具介绍及数据备份
一.IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 二.MySQL数据备份 # ...
- GitHub+Hexo 搭建个人网站
GitHub+Hexo 搭建个人网站 转自 https://www.sufaith.com/article/561.html 一.创建GitHub Pages站点 GitHub Pages是一种静态站 ...