读取非结构化CSV

时间:2017-04-05 09:48:01

标签: python 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

5 个答案:

答案 0 :(得分:4)

您可以使用空列表评估为break并使用while循环的事实,而不是使用false

while(row in reader):
    result+=[row]

答案 1 :(得分:1)

你可以使用itertools.takewhile打破你的状况,这会产生一个很好的单行:

import itertools

result = list(itertools.takewhile(bool,reader))

当该行为空时,转换为bool会产生Falsetakewhile会停止在您的阅读器上进行迭代。

转换为list仅用于显示目的。如果您只想迭代行(这可以避免创建列表),您不必转换

BTW:您的输入文件有一些额外的空格,使读者失败。修好它们后,我得到了以上一行:

[['header_1', 'header_2', 'header_3'], ['a', 'b', 'c'], ['1', '2', '3']]

答案 2 :(得分:1)

你可以使用一台发电机,虽然它不是很短:

{{1}}

答案 3 :(得分:0)

使用代码段的解决方案

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"']]

答案 4 :(得分:0)

当我运行你的代码时,在Python 2或3下,我得到一个csv.Error异常:

  File "so1.py", line 7, in <module>
    for row in reader:
_csv.Error: ';' expected after '"'

CSV“标准”中的字段分隔符周围不允许有空格。但是,当我将strict设置为False时,我得到三个数据行和一个空行,然后输出停止,因为break语句终止循环的执行。用break替换continue(终止循环)(结束此迭代)给出第四行:['Some footer text', ' maybe more.']

因此,如果您想处理数据错误,您的测试似乎需要更具体一些 - 可能只测试三个值,并忽略任何具有不同数字的行?