Pythonを使用してcsvファイルを編集するときにヘッダーをスキップする


209

以下のコードを使用して、Pythonでcsvを編集しています。コードで呼び出される関数は、コードの上部を形成します。

問題:下記のコードで2行目からcsvの編集を開始したいのですが、ヘッダーを含む1行目を除外します。現在、1行目のみに関数を適用しており、ヘッダー行が変更されています。

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

row変数をに初期化してこの問題を解決しようとしました1が、機能しませんでした。

この問題の解決を手伝ってください。


回答:


370

あなたのreader変数を使用すると、行を取り出すことをループすることで、反復可能です。

ループの前に1つの項目をスキップnext(reader, None)するには、呼び出して戻り値を無視します。

コードを少し単純化することもできます。開いたファイルをコンテキストマネージャとして使用して、自動的に閉じます。

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

ヘッダーを未処理の出力ファイルに書き込む場合も簡単です。出力をnext()に渡しますwriter.writerow()

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)

22
別の方法を使用することもできますfor row in islice(reader, 1, None)- nextほとんどの単純な「1行をスキップする」ジョブよりも明確ではありませんが、複数のヘッダー行をスキップする(または特定のチャンクのみを取得するなど)には非常に便利です
Jon Clements

使用を検討しますtry: writer.write(next(reader))... except StopIteration: # handle empty reader
Jon Clements

@JonClements:たぶん。これはtry:/ について教える必要なく十分に機能しますexcept:
Martijn Pieters

1
@JonClements:明示的なnext反復の利点は、「無料」であるということです。各反復に永久に追加される(確かに非常に少量の)オーバーヘッドをisliceラップしreaderます。consume以下からのレシピitertoolsの場合には、その後の使用法にラッピングを追加することなく、すぐに多くの値をスキップするために使用することができisliceなければなりませんstartが、ノーendので、オーバーヘッドがあなたに何を得ていません。
ShadowRanger、2016年

120

これを解決する別の方法は、ヘッダー行を「スキップ」し、それを使用して名前付きインデックスを許可するDictReaderクラスを使用することです。

次のように「foo.csv」が与えられます。

FirstColumn,SecondColumn
asdf,1234
qwer,5678

次のようにDictReaderを使用します。

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=',')
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])

21
質問はXY問題の例のようですので、これが本当の答えだと思います
MariusSiuram 2016

3
DictReaderは間違いなく進むべき道です
Javier Arias

4
DictReaderを構築するときにフィールド名パラメーターを省略した場合にのみ機能することに注意してください。ドキュメントごと:docs.python.org/2/library/csv.htmlをIf the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.参照してください
BuvinJ

7

実行すると、row=1あなただけのループの結果とすることを上書きしますので、何も変更されません。

あなたは何をしたいnext(reader)1行をスキップします。


に変更しようとしましたfor row in next(reader):が、IndexError: string index out of rangeエラーが発生しました

forループの前に使用:next(reader); for row in reader:....
dlazesz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.