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

时间:2013-01-16 23:57:51

标签: python parsing csv

我之前没有使用过csv module中的python,但它似乎很方便使用。

问题是我试图读取的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

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

1 个答案:

答案 0 :(得分: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())]

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

  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;重复的标题行已被删除。
  6. 如果您想逐行处理文件而不是一次性将其读入一个列表,只需将lines的列表理解更改为生成器表达式,方法是更改​​[row for row ...]进入(row for row ...)。然后你可以遍历lines,但是在你循环之后,每一行都会被遗忘(就像你首先做for row in reader一样)。

相关问题