查找csv文件中的列数

时间:2012-07-03 11:47:06

标签: python csv

我的程序需要读取可能有1,2或3列的csv文件,并且需要相应地修改其行为。在迭代器运行之前,是否有一种简单的方法可以检查列数而不“消耗”一行?以下代码是我能管理的最优雅的代码,但我更愿意在for循环开始之前运行检查:

import csv
f = 'testfile.csv'
d = '\t'

reader = csv.reader(f,delimiter=d)
for row in reader:
    if reader.line_num == 1: fields = len(row)
    if len(row) != fields:
        raise CSVError("Number of fields should be %s: %s" % (fields,str(row)))
    if fields == 1:
        pass
    elif fields == 2:
        pass
    elif fields == 3:
        pass
    else:
        raise CSVError("Too many columns in input file.")

修改:我应该包含有关我的数据的更多信息。如果只有一个字段,则必须包含科学记数法的名称。如果有两个字段,则第一个字段必须包含名称,第二个字段必须包含链接代码。如果有三个字段,则附加字段包含一个标志,该标志指定名称当前是否有效。因此,如果任何行包含1,2或3列,则所有列都必须具有相同的值。

5 个答案:

答案 0 :(得分:22)

您可以使用itertools.tee

  

itertools.tee(iterable [,n = 2])
  从a返回n个独立迭代器   单一可迭代。

例如

reader1, reader2 = itertools.tee(csv.reader(f, delimiter=d))
columns = len(next(reader1))
del reader1
for row in reader2:
    ...

请注意,完成后删除对reader1的引用非常重要 - 否则tee必须将所有行存储在内存中以防再次呼叫next(reader1)

答案 1 :(得分:11)

这似乎也有效:

import csv

datafilename = 'testfile.csv'
d = '\t'
f=open(datafilename,'r')

reader=csv.reader(f,delimiter=d)
ncol=len(next(reader)) # Read first line and count columns
f.seek(0)              # go back to beginning of file
for row in reader:
    pass  #dostuff

答案 2 :(得分:4)

如果用户为您提供包含较少列的CSV文件,会发生什么?是否使用默认值?

如果是这样,为什么不用空值扩展行呢?

reader = csv.reader(f,delimiter=d)
for row in reader:
    row += [None] * (3 - len(row))
    try:
        foo, bar, baz = row
    except ValueError:
        # Too many values to unpack: too many columns in the CSV
        raise CSVError("Too many columns in input file.")

现在bar和baz将至少为None,异常处理程序将处理超过3项的任何行。

答案 3 :(得分:1)

我建议这样一种简单的方法:

with open('./testfile.csv', 'r') as csv:
     first_line = csv.readline()
     your_data = csv.readlines()

ncol = first_line.count(',') + 1 

答案 4 :(得分:-1)

我会按如下方式重建它(如果文件不是太大):

import csv
f = 'testfile.csv'
d = '\t'

reader = list(csv.reader(f,delimiter=d))
fields = len( reader[0] )
for row in reader:
    if fields == 1:
        pass
    elif fields == 2:
        pass
    elif fields == 3:
        pass
    else:
        raise CSVError("Too many columns in input file.")