读取带有重复标题的CSV文件

the*_*lse 2 python csv parsing

我没有使用过csv modulepython前,但似乎不够得心应手.

问题是我试图读取的CSV文件包括文件中的标题(索引).

像这样的东西:

A, B, C, D, E, F
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
A, B, C, D, E, F
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
A, B, C, D, E, F
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
Run Code Online (Sandbox Code Playgroud)

我可以使用csv module原样,还是我必须自己解析.

Dou*_*gal 5

您只需检查是否只读取标题行即可按原样使用它.例如,使用DictReader,您可能会这样做:

with open('file.csv') as f:
    reader = csv.DictReader(f)
    lines = [row for row in reader
             if not all(k == v for k, v in row.iteritems())]
Run Code Online (Sandbox Code Playgroud)

这将对您的示例文件起作用的方式是:

  1. DictReader构造函数读取第一个标题行,确定该字段命名"A", "B", "C", "D", "E", "F".
  2. 迭代reader然后返回字典{"A": "1", "B": "2", ...}.
  3. 列表理解在lines查看每个行字典.它会首先看到像这样的字典{"A": "1", ...}.all(k == v for k, v in row.iteritems())循环键和行的值,设置例如k = "A"v = "1".无论它首先看到哪一个取决于字典决定迭代的方式,它都会看到k != v,因此all()调用将是False,这意味着该行使其进入列表lines.
  4. 当它到达重复的标题行时,它会看到类似的字典{"A": "A", "B": "B", ...}.然后,由于键等于每个字典元素的值,因此all()调用将返回True,并且列表理解中的条件将是False,这意味着该行不会使其进入最终列表.请注意,如果标题行中的标题行间距可能不同,则您需要在调用中.strip()比较它们之前调用键/值all().
  5. 最后,lines您的样本文件将等于[{"A": 1, "B": 2, ...}] * 9; 重复的标题行已被删除.

如果要逐行处理文件而不是一次将其读入一个列表,只需将列表理解更改为lines生成器表达式,方法是将其更改[row for row ...](row for row ...).然后你可以循环lines,但在你循环后,每一行都会被遗忘(就像你for row in reader在第一时间那样).