Найти количество столбцов в файле 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 столбца, все они должны быть одинаковыми.
Ответы
Ответ 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.")