33

私のプログラムは、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つのフィールドがある場合、最初のフィールドには名前が含まれ、2番目のフィールドにはリンクコードが含まれている必要があります。3つのフィールドがある場合、追加のフィールドには、名前が現在有効かどうかを指定するフラグが含まれています。したがって、いずれかの行に1、2、または3列がある場合、すべてが同じである必要があります。

4

5 に答える 5

30

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)

于 2012-07-03T11:52:07.037 に答える
20

これもうまくいくようです:

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 #do stuff
于 2012-07-03T12:06:40.347 に答える
4

ユーザーが列数の少ないCSVファイルを提供するとどうなりますか?代わりにデフォルト値が使用されますか?

もしそうなら、代わりにnull値で行を拡張してみませんか?

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項目より長い行を処理します。

于 2012-07-03T11:52:47.430 に答える
3

私はこのような簡単な方法を提案します:

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

ncol = first_line.count(',') + 1 
于 2019-06-21T01:28:54.390 に答える
-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.")
于 2012-07-03T12:09:29.193 に答える