2016-10-24 4 views
0

ユーザーの入力は、実験の名前とデータを含むファイルです。データ操作後、ファイル内のどのサンプル(行)がどの実験に対応しているかを辞書で保存しました。例えば 、(時々サンプルがいくつかの実験、あるいは1つまたはnoneのいずれかに属することができる)辞書として保存された複数のファイルを開く

exp_sample["sample1"]=['experiment5','experiment6'] 
exp_sample["sample3"]=['experiment5'] 

(第2時間)、再度データファイルを解析する際Iは、対応する実験ファイルにサンプル行を書きたいです。つまり、データファイルを解析中に、すべての実験ファイルを開く必要があります。私の考えは以下の通りです:

experiment_files = {exp: open(exp+".fastq",'w') for exp in experiments} 
for read in SeqIO.parse(fastq, 'fastq'): 
    experiment = exp_sample[sample.id] 
    #if sample belongs only to one experiment 
    #or sample belongs to two the same experiments 
    if len(experiment)==1 or (len(exp)==2 and (exp[0]==exp[1])) 
     SeqIO.write(read,exp_files[experiment[0]],'fastq') 
(x.close() for x in experiment_files.values()) 

私の質問は、それはdictに保存されたファイルを開くと、その方法でそれらを閉じるために合法的ですか?それともそれを行うための他のより洗練された方法がありますか?

PS。私は、対応する実験のリストにサンプル行を保存しておき、すべての実験記録を実験ファイルに書き込むことができましたが、データファイルは数GBにすることができます。

+1

'with'文を使って' experiments'を2回反復するのではなく '実験'のループでコンテキストマネージャを使うべきだと思います。 –

+0

@OrDuan私は実験で2回反復しません。 SeqIO.parse(fastq、 'fastq') – Anni

+0

最後にそのようなジェネレータ式を使用しても、その副作用のためだけでは貧弱な方法であるとはいえ、そうするのは合法です。この[私の答え](http://stackoverflow.com/a/21683192/355230)に示されているものを別の質問に使用することによって、あなたはそれを正式化することができます。 – martineau

答えて

0

私がコメントで議論した後、私は私の元の答えを更新します。

複数のファイルを開く場合は、コンテキストマネージャExitStackを使用してファイルを開くことができます。ここで

はサンプルコードです:

with ExitStack() as stack: 
    files = [stack.enter_context(open(fname)) for fname in filenames] 

filesリストの各要素は、あなたが開いつのファイルを表します。

+0

元の答えを変更した方が良いでしょう。削除された回答は実際には削除されないことを忘れないでください:10k +担当者が誰でもそれらを見ることができます。 –

+0

@OrDuan実験名 'SeqIO.write(read、exp_files [experiment [0]]、 'fastq')に応じてアクセスしなければならないので、開いているファイルを辞書に保存しています。 – Anni

+0

@Anniあなたが作成した辞書を使用してください。実験のexpのための '{exp:stack.enter_context(open(exp +"。fastq "、 'w')}'なので、 'close'メソッドを使う必要はありません –

関連する問題