Py学习  »  Python

用python玩转csv文件:csv模块

一个普普通通简简单单平平凡凡的神 • 5 年前 • 526 次点击  

csv文件具有格式简单,快速存取,兼容性好等特点,工程、金融、商业等很多数据文件都是采用csv文件保存和处理。工作中数据处理也用到了csv,简要总结下使用经验,特别是那些由于本地兼容性导致的与官方文档的差异使用

csv(comma Seperated Values)文件的格式非常简单,类似一个文本文档,每一行保存一条数据,同一行中的各个数据通常采用逗号(或tab)分隔。python自带了csv模块,专门用于处理csv文件的读取和存档。

csv模块中,主要由两种方式存取csv文件:函数方法;类方法。

下面首先介绍简单介绍读写csv文件的两种方法,然后结合用于解析csv文件的属性参数集dialect,具体介绍读写csv文件的技巧和实例

一、函数方法(list方法)

csv.reader(f [, dialect='excel'][optional kwargs]) #返回csv阅读器(本质是一个迭代器,具有__next__()、__iter__()方法),可通过迭代读取csv文件内容。f为打开csv文件的文件对象,注意,实测文件应该用text模式(r或rt)打开,而不是官方文档的binary模式打开(会报_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?))。dialect规定csv文件解析所采用的属性集,也可通过关键字参数修改指定属性,下文由详细介绍和实例。

csv.writer(f [, dialect='excel'][optional kwargs]) #返回csv写入器,其可将序列对象(list等)写入到csv文件中,写入方法为writerow()、writerows(),实例中介绍。f为被写入的csv文件对象,同样地,实测文件应该用text模式(w或wt)打开,而不是官方文档的binary模式打开

l = []
with open('test1.csv','rt') as f: 
   cr = csv.reader(f)
   for row in cr:
       print(row)
       l.append(row) #将test.csv内容读入列表l,每行为其一个元素,元素也为list
with open('1.csv','wt') as f2:
   cw = csv.writer(f2)
   #采用writerow()方法
   for item in l:
      cw.writerow(item) #将列表的每个元素写到csv文件的一行
   #或采用writerows()方法
   #cw.writerows(l) #将嵌套列表内容写入csv文件,每个外层元素为一行,每个内层元素为一个数据
test1.csv
1.csv

注意:1.csv中,每行数据间有一个空行,这是由于lineterminator属性导致的,下文介绍修正方法。

二、类方法(dict方法)

csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds) #建立类字典方式的csv阅读器(迭代器)。f为打开csv文件的文件对象,同样地,实测文件应该用text模式(r或rt)打开。fieldnames(list等)为字典的key值(相当于列标题),每个key对应csv文件中的一列,如不指定,则默认读取的文件第一行元素为key。

csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) #建立类字典方式的csv写入器,具有writeheader(),writerrow(rowdict),writerows(rowdicts)方法。f为文件类型对象,可为打开csv文件的文件对象(w或wt模式打开)。fieldnames(list等)为字典的key值(列标题),每个key对应csv文件中的一列,必须指定

l = []
with open('test2.csv','rt') as f: 
   cr = csv.DictReader(f)
   for row in cr:
       print(row)
       l.append(row) #将test2.csv内容读入列表l,每行为其一个元素,元素为dict
                     #key为标题(未指定时为读取的第一行),value为对应列的数据
with open('2.csv','wt') as f2:
   cw = csv.DictWriter(f2,fieldnames=['标题%d' % i for i in range(1,7)])
   cw.writeheader() #将fieldnames写入标题行
   #采用writerow()方法
   for rowdict in l:
      cw.writerow(rowdict) #将列表的每个元素(dict)按照对应的键值对写到csv文件的一行
   #或采用writerows()方法
   #cw.writerows(l) #将dict组成的list整体写入csv文件,每个dict为一行,每个value为一个数据
test2.csv
2.csv

注意:2.csv同样存在空行问题。

三、csv文件属性集

csv文件写入、读取都需要用到csv文件的属性集dialect(也可称之为“方言”^_^),其主要包括:

  • 分隔符delimiter(最重要)。用于将同一行中的各个数据分隔开,通常逗号(','),也有用tab('\t')的。
  • 换行符lineterminator(也很重要)。用于区分不同行的数据,通常为'\r\n'(由于操作系统原因,该换行符在写入csv时,可能会造成各行数据之间多出一个空行,详见上文示例),也有用'\n'。
  • 引用符quotechar。用于引用包含特殊字符(如分隔符、引用符、换行符)的区域,通常为双引号('"')。
  • 转义符escapechar。用于在quoting设置为QUOTE_NONE时跳过转义符后的分隔符(即将该分隔符不作为分隔符,而是作为内容读入)、在doublequote设置为False时跳过转义符后的引用符(即将该引用符不作为引用符,而是作为内容读入)。类似于python'\',可设为任意字符(详见下文示例)
  • 引用模式quoting。指定特殊字符的表达形式。
    • 0表示csv.QUOTE_MINIMAL(最小引用,Excel生成的csv)。
    • 1表示csv.QUOTE_ALL(引用所有,Unix生成的csv)。
    • 2表示QUOTE_NONNUMERIC(引用非数字)。
    • 3表示csv.QUOTE_NONE(不引用,表示特殊字符是不被引用符包围的)。
  • 引用符引用模式doublequote。指定引用引用符自身的方式。
    • True表示采用双重引用符形式('""')。
    • False表示采用在引用符前置转义符的形式(如'\"'。注:如未同时设置escapechar,则将报错)。
  • 是否启用严格模式strict。如为True,则在读入的csv文件格式比较差时报错。通常采用默认的False。

csv模块已经内置了3个属性集:

  • csv.excel:采用逗号分隔的Excel格式csv
    • delimiter = ','
    • doublequote = True
    • lineterminator = '\r\n'
    • quotechar = '"'
    • quoting = 0
    • skipinitialspace = False
    • escapechar = None
  • csv.excel_tab:采用tab分隔的Excel格式csv
    • delimiter = '\t' #除分隔符外,其他继承自csv.excel类
  • csv.unix_dialect:采用逗号分隔的Unix格式csv
    • delimiter = ','
    • doublequote = True
    • lineterminator = '\n'
    • quotechar = '"'
    • quoting = 1
    • skipinitialspace = False
    • escapechar = None

除此以外,用户自己也可通过csv.register_dialect()注册新的属性集,或者更简单地,在调用csv读写命令时,直接通过关键字参数指定各属性

四、csv写入间隔空行问题(换行符实例)

回过头来看第一、二节,写入的csv文件均在数据行之间存在空行。这是因为采用了默认的csv.excel属性集,换行符为'\r\n',由于操作系统原因,该换行符在写入csv时,可能会造成各行数据之间多出一个空行

解决该问题很简单,在调用csv写入器时,直接指定换行符为'\r'或'\n'即可

l = []
with open('test1.csv','rt') as f: 
   cr = csv.reader(f)
   for row in cr:
       print(row)
       l.append(row) #将test.csv内容读入列表l,每行为其一个元素,元素也为list
with open('1a.csv','wt') as f2:
   cw = csv.writer(f2, lineterminator = '\n')
   #采用writerow()方法
   for item in l:
      cw.writerow(item) #将列表的每个元素写到csv文件的一行
   #或采用writerows()方法
   #cw.writerows(l) #将嵌套列表内容写入csv文件,每个外层元素为一行,每个内层元素为一个数据
1a.csv

五、转义符实例

第三节介绍了转义符的功能,下面用实例示范一下。

l = []
with open('test1.csv','rt') as f: 
   cr = csv.reader(f)
   print(cr.__next__())

以上程序中,无转义符,将输出:['1', '2', '3', '4', '5', '6']。

l = []
with open('test1.csv','rt') as f: 
   cr = csv.reader(f, escapechar = '3')
   print(cr.__next__())

以上程序中,将字符'3'设置为转义符,将输出:['1', '2', ',4', '5', '6']。

可见,转义符'3'本身不再输出,且其后紧跟的分隔符','作为内容输出,不再作为分隔符。


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/VkcegYCP1D
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/21012
 
526 次点击