3

我以前没有使用过csv modulein 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,还是必须自己解析。

4

1 回答 1

6

您可以通过检查您是否只是阅读标题行来按原样使用它。例如,使用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())循环遍历行的键和值,设置 egk = "A"v = "1". 无论它首先看到哪个,取决于字典决定如何迭代,它会看到k != v,因此all()调用将是False,这意味着该行将其放入 list lines
  4. 当它到达一个重复的标题行时,它会看到一个像{"A": "A", "B": "B", ...}. 然后,由于键等于每个字典元素的值,all()调用将返回True,列表推导中的条件将是False,这意味着该行不会进入最终列表。请注意,如果您的标题行可能有不同的间距,您需要先调用.strip()键/值,然后再在all()调用中比较它们。
  5. 最后,lines您的示例文件将等于[{"A": 1, "B": 2, ...}] * 9; 重复的标题行已被删除。

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

于 2013-01-17T00:06:12.880 回答