[英]Read unstructured CSV
我想解析给定的csv文件,看起来像
"header_1" ; "header_2"; "header_3" "a" ; "b" ; "c" "1" ; "2" ; "3" Some footer text; maybe more.
仅解析正确且正确的结构化字段。 我该如何执行?
以下代码可以完成这项工作:
with open(path) as csv_file:
reader = csv.reader(csv_file, delimiter=";", strict=False)
result = []
for row in reader:
if row == []:
break
result += [row]
是否有一个更聪明的pythonic解决方案,无需检查行是否为空? 通常,我更喜欢DictReader 。
除了使用break
您还可以使用以下事实:空列表评估为false
而使用while循环:
while(row in reader):
result+=[row]
您可以使用itertools.takewhile
打破状况,这将创建一个不错的单行代码:
import itertools
result = list(itertools.takewhile(bool,reader))
当该行为空时,将其转换为bool
生成False
并且takewhile
停止在您的阅读器上进行迭代。
转换为list
仅用于显示目的。 如果您只想在行上进行迭代,则不必进行转换(这避免了创建列表)
顺便说一句:您的输入文件有一些额外的空间,使阅读器失败。 修复它们后,我得到了上面的代码:
[['header_1', 'header_2', 'header_3'], ['a', 'b', 'c'], ['1', '2', '3']]
您可以使用生成器,尽管生成器并不完全短:
def get_lines(path):
for line in csv.reader(open(path), delimiter=";"):
if line:
yield line
else:
break
f = [i for i in get_lines("blah.csv")]
print f
使用代码段的解决方案
import csv
with open("a.csv") as csv_file:
reader = csv.reader(csv_file, delimiter=";", strict=False)
result = []
#First get everything in list
for row in reader:
result.append(row)
#Filter list only for row with 3 elements.Blank line got ignored also
final = [r for r in result if len(r)==3]
print final
输出:
C:\Users\dinesh\Desktop>python demo.py
[['header_1 ', ' "header_2"', ' "header_3"'], ['a ', ' "b" ', ' "c"'], ['1 ', '"2" ', ' "3"']]
当我在Python 2或3下运行代码时,出现csv.Error
异常:
File "so1.py", line 7, in <module>
for row in reader:
_csv.Error: ';' expected after '"'
CSV“标准”中字段分隔符周围不允许有空格。 但是,当我将strict
设置为False
时,我得到了三行数据和一个空行,然后输出停止,因为break
语句终止了循环的执行。 用continue
(结束迭代)替换break
(终止循环)会得到第四行: ['Some footer text', ' maybe more.']
。
因此,如果您想处理数据错误,则看来您的测试需要更加具体-也许只测试三个值,而忽略具有不同数字的任何行?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.