2017-07-07 6 views
0

ファイルのデータを抽出しようとしています。その目的のために、ファイルを読み込むスクリプトを作成し、いくつかのキーワードが検出された場合はコピーを開始し、空白行が見つかるとコピーを停止します。私はそれがあまりにも悪くないと思うが、働いていない。ファイルの情報を正しく抽出できない

私が書いたPythonスクリプトは次のとおりです。

  CURRENT BEST VALUE OF HEAT OF FORMATION = -1161.249249 
    cycles=200 pm6 opt singlet eps=80 charge=-1 


    C -3.87724655 +1 1.30585983 +1 4.53273224 +1 
    H -7.60628859 +1 0.53968618 +1 3.72680573 +1 
    O -4.76978297 +1 4.45409715 +1 1.42608903 +1 
    H -4.66890488 +1 4.47267425 +1 2.41952335 +1 
    H -5.59468165 +1 3.93399792 +1 1.27757138 +1 


********************** 
*     * 
* JOB ENDED NORMALLY * 
*     * 
********************** 
が、それは

を「構造が見つからない」印刷します

def out_to_mop (namefilein, namefileout): 
    print namefilein 
    filein=open(namefilein, "r") 
    fileout=open(namefileout, "w") 
    lines = filein.readlines() 
    filein.close() 

    #look for keyword "CURRENT.." to start copying 
    try: 
     indexmaxcycle = lines.index("   CURRENT BEST VALUE OF HEAT OF FORMATION") 
     indexmaxcycle += 5 
    except: 
     indexmaxcycle = 0 

    if indexmaxcycle != 0: 
     while lines[indexmaxcycle]!=" \n": 
      linediv = lines[indexmaxcycle].split() 
      symbol = linediv[0] 
      x = float(linediv[1]) 
      indexmaxcycle += 1 
      fileout.write("%s \t %3.8f 1 \n" %(symbol, x)) 
    else: 
     print "structure not found" 
     exit() 
    fileout.close() 

この関数は、このファイルから情報を抽出することになっているがfile1.outと呼ばれます少し助けてくれますか?

+0

あなたは 'except exception exceptions with e:'、 'print(e)'を使って 'exception'文を完成させた方がよいでしょう。間違ったものが表示されます – PRMoureu

答えて

1

あなたが「、コード行

indexmaxcycle = lines.index("   CURRENT BEST VALUE OF HEAT OF FORMATION") 

indexメソッドのドキュメントが言うと構造体の先頭を見つける値xは最初の項目のリストにゼロベースのインデックスを返すようにしてみてください。そのような項目がない場合、ValueErrorを発生させます。しかし、あなたが探している行はファイル行の一つではありません。実際のファイル行は

  CURRENT BEST VALUE OF HEAT OF FORMATION = -1161.249249 

です。最後の数字は検索文字列にはありません。したがって、indexメソッドでは例外が発生し、indexmaxcycleという値が0になります。あなたは明らかに事前にファイルの行のすべての内容を知らないので

は、あなたが入力線を介してループを自分でとは検索文字列を含む行を検索しin演算子を使用する必要があります。また、この方法でstartswith文字列メソッドを使用することができます。

for j, line in enumerate(lines): 
    if line.startswith("   CURRENT BEST VALUE OF HEAT OF FORMATION"): 
     indexmaxcycle = j + 5 
     break 
else: 
    indexmaxcycle = 0 

私は例外がこのコードのために提起することができる方法を見ていないので、私は、ここにtry..except構造を落としました。もちろん私は間違っている可能性があります。

+0

、ありがとう。そして、私はどのように "フォーメーションの熱の現在の最高値"を探すことができますか? – santimirandarp

+0

行を '='で分割し、結果の配列の最初の要素を取ることができます。 –

+0

@HernanMiraola:質問を入力したときと同じように、コードを入力していました。私のコードの終わりを見てください。 –

1

完全一致を探していますが、テキストファイルの行が探しているパターンよりも長くなっています。代わりに、行の先頭を検索しよう:

pattern = "   CURRENT BEST VALUE OF HEAT OF FORMATION" 
try: 
    indexmaxcycle = [i for (i,s) in enumerate(lines) if s.startswith(pattern)][0] 
    indexmaxcycle += 5 
etc. 

[i for (i,s) in enumerate(lines) if s.startswith(pattern)]は、あなたのパターンで始まるすべての要素のインデックスを提供します。 [0]を追加すると、最初のものが得られます。それが最初の一致が見つかるまで、これが唯一のリストを検索します

pattern = "   CURRENT BEST VALUE OF HEAT OF FORMATION" 
try: 
    indexmaxcycle = next((i for (i,s) in enumerate(lines) if s.startswith('foo'))) + 5 
except: 
    etc. 

は、私はちょうどあなたの代わりにリスト内包のジェネレータ式を使用する場合は、これをスピードアップすることができます気づきました。

+1

あなたのコードは動作しますが、目的の行がファイルの先頭または近くにあってもファイル全体を検索します。そうすれば、大きな入力ファイルではルーチンが遅くなります。 –

+0

あなたは正しいです、ありがとうございます。しかし、私は既にそれに気づき、ジェネレータ表現を使用するバージョンを追加しました。 ) – Johannes

+1

Python3では 'generator.next()'の代わりに 'next(generator)'を使います。 – Greg

関連する問題