Python csv 模块

今天的练级主题是Python的csv模块,直接找到Python官方文档的csv模块页:

http://docs.python.org/2/library/csv.html#module-csv


 首先,我做了一个稍不是很正常的excel文档来做测试,文档内容如图,

  

 为什么不是很正常呢,因为本来就是","分割的值表,如果值里面包含了","怎么办?观察产生的csv的文本:


这里之所以要截图不用文本的复制粘贴,下文有玄机。这个文档除了值中包含","还包含了双引号和单引号,因此用自己写程序读这个file可能难免会出BUG,至少不能像昨天一样简单的.split(",")可以搞定了。


所以今天要学用的就是csv模块,首先import。

>>> import csv
>>>

然后打开文档看看,

>>> with open('HelloWorld.csv') as csvfile:
...     print csvfile.read()
... 
"4,,5",7&8,That's it,,,,1+2
>>> 

前面这个with open是csv模块官方文档给的一个语句结构,Google了一下,用with打开的一个好处是会自己擦屁股,比如with open之后会自动close()。除此之外,个人理解"with open(filename) as f" == "f = open(filename)",如果有高手觉得这个我说的不对的话,请不吝赐教。


说完with之后,发现这个print出来的东西不对!前面两行直接被吞掉了,查看了一下不是with的问题。而是open的问题,本来open这个内置函数应该是明天的练级主题,既然今天出来了,当然也十分欢迎。看一下open的官方文档说明。


首先是open的语法

open(name[, mode[, buffering]])

里面的模式(mode)参数中,'r','w','a'分别代表只读,写入和增加,这个估计都早知道了,对于个人来说比较新的是'U'和'b','b'是支持二进制打开,即使文档不是二进制文件,使用这个参数也没有坏处,'U'是支持universal newlines的参数,所谓universal newlines的意思是各个操作系统平台所用的换行附是不同的,比如'\n'是Python默认的换行符,'\r\n'则是windows上默认的,此外还有'\r'和'^M',就是本文所产生的csv文档中所使用的换行符,这也是为什么之前要使用截图而不是直接复制粘贴文字的原因,写了那么多直接来个测试看看用'U'模式打开文档会不会有区别。

>>> with open('HelloWorld.csv','Urb') as csvfile:
...     print csvfile.read()
... 
1,"2,3",4.5,5-6,7/8,9~0,1+2
"""11""",12,19%,#123,,,
"4,,5",7&8,That's it,,,,
>>> 

很好,3行都print出来了。


但是光Print出来只是第一步,我们希望把这个东西放到一个列表或者字典里,csv模块提供了很有用的两个参数,一个是delimiter分割符默认是',',另一个是quotechar引用符,默认是'"',在这个例子里,直接用默认就好,话说这个虽然叫csv模块,但是改成处理tsv文档也就改一个参数的问题。

>>> with open('HelloWorld.csv','Urb') as csvfile:
...     content = csv.reader(csvfile)
...     for line in content:
...         print line
... 
['1', '2,3', '4.5', '5-6', '7/8', '9~0', '1+2']
['"11"', '12', '19%', '#123', '', '', '']
['4,,5', '7&8', "That's it", '', '', '', '']
>>> 

由此,我发现了两点,一是这个reader的返回值是一个迭代器,另一点是这个迭代器yeild的每一项都是经过split之后的list对象。


我接下来尝试了一下csv.writer方法

>>> with open('HelloWorld.tab','wb') as tabfile:
...     tabwriter = csv.writer(tabfile, delimiter='\t', quotechar='"')
...     tabwriter.writerow(['Spam']*5)
...     tabwriter.writerow(['Hello','World'])
... 
>>> content = []
>>> for line in csv.reader(open('HelloWorld.csv','Urb')):
...     content.append(line)
... 
>>> with open('HelloWorld.tab','wb') as tabfile:
...     tabwriter = csv.writer(tabfile, delimiter = '\t', quotechar='"')
...     for line in content:
...         tabwriter.writerow(line)
... 
>>> print open("HelloWorld.tab").read()
1	2,3	4.5	5-6	7/8	9~0	1+2
"""11"""	12	19%	#123
4,,5	7&8	That's it
>>> 

个人觉得csv的writer使用感觉不是那么好,首先writer很像一个handle,需要使用writer.writerow()才能写入,第二,一行一行写,写入的对象类型需要一维列表,一整块地写入则需要一个二维列表,相对麻烦。第三,没有.close()方法,需要用f.close()直接close整个file,或者用with打开file。关于这些“缺点”,如果有理解的不对的话,请高手们不吝赐教。


最后我尝试了一下使用dictreader和dictwriter,虽然最后查到了一个靠谱的使用方法:


http://bytes.com/topic/python/answers/910694-how-parse-csv-using-dictreader


但是我觉得这个用法比较晦涩,至少目前我如果想实现类似的功能,我会用更简单易懂粗暴的方法。


嗯,今天的csv模块就先到这,本来明天的open函数似乎也在今天解决了,那么下次的任务就是sys模块了,嘿嘿,那可是个很好用的模块,估计下次还会顺带着学习一下os模块哦。

===============================================================================
附:
这些“习题”源自陈皓叔叔的博文《程序员练级技术攻略》:
http://coolshell.cn/articles/4990.html
我希望尝试跟着他推荐的方式练级,同时把每日的心得放到博客上来供大家分享,也希望各位程序员大牛们指导。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值