2016-10-24 4 views
0

Benutzereingabe sind die Namen der Experimente und eine Datei mit Daten. Nach der Datenmanipulation habe ich in einem Diktat gespeichert, welches Sample (Zeile) in der Datei welchem ​​Experiment entspricht. Zum Beispiel kann (manchmal kann Probe entweder gehören mehrere Experimente, oder eine oder keine)Öffnen Sie mehrere Dateien als Wörterbuch

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

Während wiederum die Daten-Datei Parsen (zum zweiten Mal) Ich habe die Probe Zeile in die entsprechenden Experimentdatei schreiben möchten. Das bedeutet, dass alle Testdateien geöffnet werden sollten, während ich die Datendatei durchsuche. Meine Idee ist folgende:

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()) 

Meine Frage ist, ist es legitim in den dict die Dateien gespeichert zu öffnen und sie dann auf diese Weise in der Nähe? Oder gibt es einen anderen, klügeren Weg?

PS. Ich weiß, ich hätte die Probenreihen in den Listen der entsprechenden Experimente speichern und dann alle Experimentdatensätze in eine Experimentdatei schreiben können, aber die Datendatei kann aus mehreren GB bestehen.

+1

Ich denke, Sie sollten den Kontextmanager in einer Schleife über "Experimente" verwenden, anstatt zweimal auf "Experimente" mit der 'with' Anweisung –

+0

@OrDuan Iteration zweimal auf Experimente Iterieren, iterieren zweimal über Datendatei, nämlich SeqIO.parse (fastq, 'fastq') – Anni

+0

Es sollte legal sein, dies zu tun, obwohl die Verwendung eines Generatorausdrucks wie dem am Ende, nur für seine Nebenwirkungen, als eine schlechte Praxis angesehen wird. Sie können es formalisieren, indem Sie verwenden, was in diesem [Antwort von mir] (http://stackoverflow.com/a/21683192/355230) zu einer anderen Frage gezeigt wird. – martineau

Antwort

0

Nachdem wir am Kommentar diskutiert haben, aktualisiere ich meine ursprüngliche Antwort. Wenn Sie mehrere Dateien öffnen möchten, können Sie dies mit dem Kontextmanager ExitStack tun. Hier

ist ein Beispielcode:

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

Jedes Element in der Liste files stellen eine Datei, die Sie öffnen.

+0

Es wäre besser gewesen, wenn Sie nur Ihre ursprüngliche Antwort geändert hätten. Denken Sie daran, gelöschte Antworten werden nicht wirklich gelöscht: Jeder mit 10k + rep kann sie sehen. –

+0

@OrDuan Ich speichere die geöffneten Dateien im Wörterbuch, weil ich Zugriff auf sie nach dem Testnamen 'SeqIO.write (lesen, exp_files [Experiment [0]], 'Fastq') brauchen' – Anni

+0

@Anni können Sie noch Verwenden Sie das von Ihnen erstellte Diktat. etwas wie das: '{exp: stack.enter_context (offen (exp +". fastq ", 'w')) für exp in experimes}} damit du nicht die Methode' close' verwenden musst –