Подтвердить что ты не робот

Найти количество столбцов в файле csv

Моя программа должна читать файлы csv, которые могут содержать 1,2 или 3 столбца, и необходимо соответствующим образом изменить его поведение. Есть ли простой способ проверить количество столбцов без "потребления" строки до запуска итератора? Следующий код является самым элегантным, с которым я мог бы справиться, но я бы предпочел запустить проверку до начала цикла 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 столбца, все они должны быть одинаковыми.

4b9b3361

Ответ 1

Вы можете использовать itertools.tee

itertools.tee(iterable [, n = 2])
Возвращает n независимых итераторов из однострочный.

например.

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

Обратите внимание, что важно удалить ссылку на reader1, когда вы закончите с ней, иначе tee будет хранить все строки в памяти, если вы еще раз вызовете next(reader1)

Ответ 2

Это тоже работает:

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

Ответ 3

Что произойдет, если пользователь предоставит вам файл 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 элементов.

Ответ 4

Я бы предложил такой простой способ:

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

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

Ответ 5

Я бы перестроил его следующим образом (если файл не слишком большой):

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.")