2017-07-05 34 views
0

コンテキスト:mafファイル(複数のアラインメントファイル)を個々のfastaファイルに変換しようとしています。私は修正する方法がわからないという同じエラーに陥っています。これはPythonには比較的新しいためです。私のコードは以下の通りです:文字列インデックスの範囲外のエラー:mafファイルからfastaファイル

open_file = open('C:/Users/Danielle/Desktop/Maf_file.maf','r') 
for record in open_file: 
    print(record[2:7]) 
    if (record[2] == 'Z'): 
     new_file = open(record[2:7]+".fasta",'w') 
     header = ">"+record[2:7]+"\n" 
     sequence = record[46:len(record)] 
     new_file.write(header) 
     new_file.write(sequence) 
     new_file.close() 
    else: 
     print("Not correct isolate.") 
open_file.close() 

私が手にエラーがある:

IndexError         
Traceback (most recent call last) 
     2 for record in open_file: 
     3  print(record[2:7]) 
----> 4  if (record[2] == 'Z'): 
     5   new_file = open(record[2:7]+".fasta",'w') 
     6   header = ">"+record[2:7]+"\n" 
IndexError: string index out of range 

私があれば、else文を削除した場合、私は期待通りに動作しますが、私はで始まる特定の種をフィルタリングしたいと思います文字Z.

誰かが私がこのように文字Zで始まる文字列だけを選択できない理由を説明するのに役立つなら、それは素晴らしいでしょう!前もって感謝します。

+0

「記録」はどのようにフォーマットされていますか?いくつかのレコードの長さが<= 2、おそらく空白のようですか? –

+0

より一般的には 'recordEnter:string index out of range'エラーが発生します。' record'が3個よりも短く、Pythonはアイテム '[2]' – patrick

+0

にアクセスできません。 – PYA

答えて

1

レコードの長さは、文がにあれば、これはあなたがあなたを変更することができます修正するには2

未満である場合にエラーを与えてその:

if (len(record) > 2 and record[2] == 'Z'): 

理想的には、前にも個別にそのようなケースを処理する必要があります。

+0

も ​​'print'ステートメントのために同じことをしたいかもしれません。 – PYA

+1

確かに、エラーは出ません。空白行を印刷します。 –

+1

@pyjgこれをスライスして印刷する必要はありません: '' [10:20] '。スライスは可能な限りスライスしますが、スライスが範囲外の場合は空のオブジェクトを返します。 –

0

これは別の回答です。

あなたが読んでいるレコードに少なくとも3文字は含まれていない可能性があるため、問題が発生しています。そのため、インデックス2を調べる前に文字列の長さをチェックする必要があります。気づいたことがあるように、3行目はクラッシュしません。

スライス演算子は、インデックス2から7にスライスして、見つかったものを返します。だから、

あなたはこれを見てみましょうしている場合:あなたが見ることができるように、それは除外され、インデックス2に、インデックス1から何かを返します

"abcd"[1:] == "bcd" 
"abcd"[1:3] == "bc" 
"abcd"[1:10] == "bcd" 
"abcd"[4:] == "" 

を。何も見つからない場合、スライス操作が停止して戻ります。

ので、長さをチェックするのと同じ結果を得るための一つの異なる方法がこれを行うには、次のようになります。

if (record[2:3] == 'Z'): 

この方法で、あなたは、インデックス2で文字をスライスしている、インデックスが、それは意志が存在する場合それ以外の場合は空の文字列を返します。つまり、スライス操作が文字列の長さを確認してインデックスを取得するよりも速いかどうかはわかりません。いくつかの点で、スライス操作は内部的にはおそらく最も可能性があります。

0

良い答え

この方法で、我々はあなたが持っていた問題を修正しても、それはもう少し効率的に行うことができます。 [2:7]のレコードを複数回スライスしている場合は、そのレコードを変数に格納する必要があります。インデックス2が結果のファイル名に存在しない場合、ファイル名は空であるとみなすことができます。ファイル名が空の場合は偽であり、そうでない場合は確かにそこに存在し、ファイル名のインデックス0はレコードのインデックス2であるため、インデックス0をチェックできます。

第2の問題は、+演算子の代わりにフォーマット文字列を使用することです。渡されたものをフォーマット文字列に変換します。フォーマットは、%sです。 FalseまたはNoneの値を渡すと、算術演算はstr + strにしか許可されないため、プログラムはクラッシュします。

open_file = open('C:/Users/Danielle/Desktop/Maf_file.maf','r') 

for record in open_file: 
    filename = record[2:7] 
    print(filename) 

    if (filename and filename[0] == 'Z'): 
     with open("%s.fasta" % filename,'w') as newfile: 
      header = ">%s\n" % filename 
      sequence = record[46:len(record)] 
      new_file.write(header) 
      new_file.write(sequence) 
    else: 
     print("Not correct isolate.") 

open_file.close() 

再フォーマットのビットと、私たちはこれで終わるだろう:彼らは自分自身を閉じて、ファイルを処理しますよう

def write_fasta(record): 
    filename = record[2:7] 
    print(filename) 

    if (filename and filename[0] == 'Z'): 
     with open("%s.fasta" % filename,'w') as new_file: 
      header = ">%s\n" % filename 
      sequence = record[46:len(record)] 
      new_file.write(header) 
      new_file.write(sequence) 
    else: 
     print("Not correct isolate.") 

maf_filename = 'C:/Users/Danielle/Desktop/Maf_file.maf' 
with open(maf_filename, 'r') as maf: 
    for record in maf: 
     write_fasta(record) 

は、可能な限りコンテキストマネージャを使用してください。したがって、明示的にclose()メソッドを呼び出す必要はありません。

関連する問題