当前位置: 首页 > 工具软件 > tsv-utils > 使用案例 >

python读取tsv文件_Python 读写 tsv

司业
2023-12-01

Python操作csv和excel的教程随处可见,可惜我遇到的是tsv, 然后可搜到的资料屈指可数,在经历了一番努力之后终于找到了解决方案,顺手还研究了一波文件读取,写下来记录一下。

首先上成果,伸手党自取:

import csv

def write_to_tsv(output_path: str, file_columns: list, data: list):

csv.register_dialect('tsv_dialect', delimiter='\t', quoting=csv.QUOTE_ALL)

with open(output_path, "w", newline="") as wf:

writer = csv.DictWriter(wf, fieldnames=file_columns, dialect='tsv_dialect')

writer.writerows(data)

csv.unregister_dialect('tsv_dialect')

def read_from_tsv(file_path: str, column_names: list) -> list:

csv.register_dialect('tsv_dialect', delimiter='\t', quoting=csv.QUOTE_ALL)

with open(file_path, "r") as wf:

reader = csv.DictReader(wf, fieldnames=column_names, dialect='tsv_dialect')

datas = []

for row in reader:

data = dict(row)

datas.append(data)

csv.unregister_dialect('tsv_dialect')

return datas

上面就是读写tsv时用到的代码了,下面写一下基础知识点。

一、科普

1、Open函数:

open(file, mode=‘r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

其中参数:mode:由两部分组成:文件模式:r、w、a,对应着只读、只写、追加模式

数据模式:b、t、+、U,对应着二进制模式,文本模式,读写模式、通用换行符,根据实际情况组合与上面的的文件模式组合使用

buffering:可能取值为:0,1, >10:代表buffer关闭,只适用于二进制模式

1:代表line buffer,只适用于文本模式

>1:表示初始化的buffer大小

encoding:表示的是返回的数据采用何种编码,一般采用utf8或者gbk

errors:可能取值有:strict,ignorestrict:字符编码出现问题的时候,会报错

ignore:编码出现问题,程序会忽略而过,继续执行下面的程序

newline:可以取的值有None, \n, \r, '',‘\r\n' ,用于转换换行符,但是这个参数只对文本模式有效:从流读取输入时,如果newline为None,则启用通用换行符模式。输入中的行可以以'\n','\r'或'\r\n'结尾,它们在返回给调用者之前被转换成'\n'。如果它是'',则启用通用换行符模式,但行结尾将返回给调用者而不会转换。如果它具有任何其它合法值,则输入行仅由给定字符串终止,并且行结尾被返回给调用者而不会转换。

将输出写入流时,如果newline为None,则写入的任何'\n'字符都将转换为系统默认行分隔符os.linesep。如果newline是''或'\n',则不会进行转换。如果newline是任何其他合法值,写入的任何'\n'字符都将转换为给定字符串。

closefd:如果closefd是False并且给出了文件描述器而不是文件名,则当文件关闭时,基本文件描述器将保持打开。如果给定文件名,则closefd必须为True(默认值),否则将产生错误。

opener:通过传递可调用对象opener可以使用自定义开启器。然后通过调用opener(文件,标志)获取文件对象的基础文件描述器。opener必须返回一个打开的文件描述器

2、csv.DictWriter函数:

DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)

创建一个对象,该对象在操作上类似常规 writer,但能将字典映射到输出行

其中参数:

fieldnames:必选参数。fieldnames 参数是由键组成的 序列,它指定字典中值的顺序,这些值会按指定顺序传递给 writerow() 方法并写入文件 fextrasaction:如果传入的字典的某些键在 fieldnames 中找不到,则可选参数extrasact-ion 用于指定要执行的操作raise:默认值,引发 ValueError

ignore:则字典中的其他键值将被忽略

restval :如果传入的字典缺少 fieldnames 中的键,则可选参数 restval 用于指定要写入的值

dialect:默认Excel,包含其他属性的容器类,用于将定义好的参数传递给特定的 reader 或 writer 实例

3、Dialect

为了更容易指定输入和输出记录的格式,特定的一组格式参数组合为一个 dialect。

支持以下属性:

Dialect.delimiter :一个用于分隔字段的单字符,默认为 ','。

Dialect.doublequote:控制出现在字段中的 引号字符 本身应如何被引出。当该属性为 True 时,双写引号字符。

如果该属性为 False,则在 引号字符 的前面放置 转义符。默认值为 True。

在输出时,如果 doublequote 是 False,且 转义符 未指定,且在字段中发现 引号字符 时,会抛出 Error 异常。

Dialect.escapechar :一个用于 writer 的单字符,用来在 quoting 设置为 QUOTE_NONE 的情况下转义 定界符,在 doublequote 设置为 False 的情况下转义 引号字符。在读取时,escapechar 去除了其后所跟字符的任何特殊含义。该属性默认为 None,表示禁用转义。

Dialect.lineterminator:放在 writer 产生的行的结尾,默认为 '\r\n'。

注:reader 经过硬编码,会识别 '\r' 或 '\n' 作为行尾,并忽略 lineterminator。

Dialect.quotechar:一个单字符,用于包住含有特殊字符的字段,特殊字符如 定界符 或 引号字符 或换行符。默认为 '"'。

Dialect.quoting:控制 writer 何时生成引号,以及 reader 何时识别引号。该属性可以等于任何 QUOTE_* 常量(参见 模块内容 段落),默认为 QUOTE_MINIMAL。

Dialect.skipinitialspace:如果为 True,则忽略 定界符 之后的空格。默认值为 False。

Dialect.strict:如果为 True,则在输入错误的 CSV 时抛出 Error 异常。默认值为 False。

二、DictWriter & Dialect

简单理一下DictWriter和Dialect的关系:Dialect是用来装参数的容器,谁的参数?DictWriter的。那么Dialect的参数直接放在DictWriter中可以吗?完全可以。那么启用Dialect的意义是?为了更容易指定输入和输出记录的格式。

比如咱们要写一个超级无敌螺旋滚动杀马特格式的csv,将所有的参数都写在DictWriter上可能会变成如下:

csv.DictWriter(wf, fieldnames=file_columns,

lineterminator = "super",

delimiter = "invincible",

doublequote = "spiral",

...)

它可能是一个很长的函数,但是引入了Dialect,不仅可以把参数都放在里面,减轻了DictWriter的负担,还可以起一个帅气、辨识度高的名字:

csv.register_dialect('handsome', lineterminator ='super', delimiter = "invincible"...)

reader = csv.DictReader(wf, fieldnames=column_names, dialect='handsome')

三、tsv & csv

最终的目的还是要回到tsv上,先一波csv和tsv的基础定义:

CSV: comma separated values;即“逗号分隔值”,用逗号分隔数据

TSV:tab separated values;即“制表符分隔值”,用制表符分隔数据

所以他们的本质区别在于分隔符的不同,tsv格式是用‘\t’分隔,而csv格式是用‘,’分隔。

分隔符,也就是:Dialect.delimiter,现在一切都明了了,修改参数delimiter即可。

然后放一下csv包中三个现成的Dialect:

class excel(Dialect):

"""Describe the usual properties of Excel-generated CSV files."""

delimiter = ','

quotechar = '"'

doublequote = True

skipinitialspace = False

lineterminator = '\r\n'

quoting = QUOTE_MINIMAL

register_dialect("excel", excel)

class excel_tab(excel):

"""Describe the usual properties of Excel-generated TAB-delimited files."""

delimiter = '\t'

register_dialect("excel-tab", excel_tab)

class unix_dialect(Dialect):

"""Describe the usual properties of Unix-generated CSV files."""

delimiter = ','

quotechar = '"'

doublequote = True

skipinitialspace = False

lineterminator = '\n'

quoting = QUOTE_ALL

register_dialect("unix", unix_dialect)

中间的excel-tab就是现有的为tsv定制的dialect了。

最后放两个文档,若有需要请自取。

Ref:

CSV 中文文档csv --- CSV 文件读写​docs.python.org

Open 文档https://docs.python.org/3.6/library/functions.html#open​docs.python.org

 类似资料: