0

私はこの単純なコードを持っています。これは、Python I/Oがどのように機能するかを理解するのに役立ちます。

inFile = open("inFile.txt",'r')
outFile = open("outFile.txt",'w')
lines = inFile.readlines()

first = True
for line in lines:
    if first == True:
        outFile.write(line)  #always print the header
        first = False
        continue
    nums = line.split()
    outFile.write(nums[3] + "\n") #print the 4th column of each row
outFile.close()

私の入力ファイルは次のようなものです:

#header
34.2 3.42 64.56 54.43 3.45
4.53 65.6 5.743 34.52 56.4
4.53 90.8 53.45 134.5 4.58
5.76 53.9 89.43 54.33 3.45

出力はファイルに正しく出力されますが、エラーも発生します。

    outFile.write(nums[3] + "\n")
IndexError: list index out of range 

データがなくなったのに次の行を読み続けたからだと思いますか?

4

3 に答える 3

2

他の人はすでにあなたの質問に答えています。これは、「常にファイルヘッダーを印刷する」ためのより良い方法であり、firstすべての反復でのテストを回避します。

with open('inFile.txt', 'r') as inFile, open('outFile.txt', 'w') as outFile:
    outFile.write(inFile.readline()) #always print the header
    for line in inFile:
        nums = line.split()
        if len(nums) >= 4: #Checks to make sure a fourth column exists.
            outFile.write(nums[3] + "\n") #print the 4th column of each row

ここではいくつかのことが起こっています:

with open('inFile.txt', 'r') as inFile, open('outFile.txt', 'w') as outFile:

このwith式は、例外が発生してwithブロックが早期に終了した場合でもファイルを自動的に閉じるため、ファイルを開くのに便利な方法です。

with注:Python 2.6では、複数のコンテキストのサポートが2.7まで追加されなかったため、2つのステートメントを使用する必要があります。例えば:

with open(somefile, 'r') as f:
    with open(someotherfile, 'w') as g:
        #code here.

outFile.write(inFile.readline()) #always print the header

fileオブジェクトは、消費されるイテレータです。がreadline()呼び出されると、バッファ位置が前方に進み、最初の行が返されます。


for line in inFile:

前述のように、オブジェクトはイテレータであるため、ループ内fileで直接使用できます。for

于 2012-07-20T21:30:16.467 に答える
2

このエラーは、ソースコードに次の行があることを示しています。

outFile.write(nums[6] + "\n")  

質問で示した6ものとは異なることに注意してください。3ファイルには2つの異なるバージョンがある場合があります。

nums行を分割した結果であり、あなたの場合は5つの要素しか含まれていないため、失敗します。

for line in lines:
    # ...
    # line is for example "34.2 3.42 64.56 54.43 3.45"
    nums = line.split() 
    print len(nums)

リストの終わりを超えてインデックスを作成することはできません。

また、コードにエラーがある可能性があります。ヘッダーを作成し、それを分割して、そこから1つの要素を書き込みます。おそらくif/elseが必要です。

for line in lines:
    if first == 1: 
        # do something with the header
    else:
        # do something with the other lines

または、ループに入る前にヘッダーを個別に処理することもできます。

于 2012-07-20T21:14:56.387 に答える
1

問題は、残りのデータと同じように「ヘッダー行」を処理していることです。つまり、ヘッダー行を識別しても、その処理をスキップすることはありません。split()つまり、実行時エラーの原因となるループのさらに下に移動することを避けないでください。

問題を解決するには、次のcontinueようにを挿入するだけです。

first = True
for line in lines:
    if first == True:
       outFile.write(line)  #always print the header
       first = False
       continue   ## skip the rest of the loop and start from the top 
    nums = line.split()
    ...

これにより、ループの残りの部分がバイパスされ、すべてが正常に機能します。

出力ファイルには次のものoutFile.txtが含まれます。

#header
54.43
34.52
134.5
54.33

そして、2番目の問題は、入力ファイルの最後に空白行があることが判明しました(以下のコメントの説明を参照してください)

:コードを再構築することもできますが、それを行うことに興味がない場合は、上記の簡単な修正により、現在のコードをすべて保持でき、1行追加するだけで済みます。他の投稿で述べたようにwith、開いているファイルの管理に使用することを検討する価値があります。これは、完了したときや例外が発生したときにもファイルを閉じるためです。

于 2012-07-20T21:15:19.170 に答える