Dateiinhalt in Liste übertragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

Ich bin blutiger Anfänger und entschuldige mich schon mal, für meine einfache Frage. Google und das Tutorial sowie die Forensuche hab ich schon benutzt, aber wahrscheinlich ist mein Problem zu trivial.
Ich arbeite mit Python 2.7 auf einer Eclipse-Platform.

Ich möchte eine txt-Datei (scaffolddna.txt) öffnen und einlesen. Der Inhalt der Datei (Buchstabenabfolge) soll dann in eine Liste (als strings) übertragen werden. Das hab ich bisher geschrieben:

#-*- coding: utf-8 -*-
f = open('scaffolddna', 'r')
f.read()
print f

Soweit gibt es auch kein Fehlermeldungen. Ich weiß jetzt aber nicht, wie ich es schaffe, den Inhalt der Datei (verkürzt: ACGT) in ein Liste zu bringen ['A', 'G', 'C','T']. Mit welchem statement macht man das? Da ich den Begriff nicht kenne, ist es auch schwierig beim suchen. Vielleicht kann mir ja jemand sagen, wonach ich suchen muss?
BlackJack

@cocolino: Dafür gibt es keine Anweisung. Da Du eine Liste haben möchtest, könntest Du mal die Dokumentation zu `list()` lesen. ;-)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hallo und willkommen im Forum,

vielleicht magst Du Dir das Tutorial durchlesen? Da stehen solch elementare Dinge erklärt.

Im Übrigen ist das jetzt schwer zu sagen, weil wir nicht wissen, wie Deine Datei *genau* aufgebaut ist. Aber ich versuche mal Folgendes (ungetestet):

Code: Alles auswählen

fname = 'scaffolddna'
seqdata = list()
with open(fname) as seqfile:
   for line in seqfile:
      seqdata.extend(list(line)) 
print seqdata # falls Du Python 3.x nutzt: print(seqdata)
Ich bin mir aber fast sicher, daß Du das gar nicht möchtest: Bei Sequenzdaten ist es meist besser sie als einen String zu haben. Außerdem würde ich Dir nicht raten das Rad neu zu erfinden: biopython dürfte viele Dinge schon können, die Du erst mühsam coden müsstest.

HTH
Christian
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

BlackJack hat geschrieben:@cocolino: Dafür gibt es keine Anweisung. Da Du eine Liste haben möchtest, könntest Du mal die Dokumentation zu `list()` lesen. ;-)
Ja, das Tutorial zu Liste hab ich schon gelesen, aber da werden die Indices immer per Hand eingegeben. Ich dachte, das geht auch automatisch.
CM hat geschrieben: vielleicht magst Du Dir das Tutorial durchlesen? Da stehen solch elementare Dinge erklärt.

Im Übrigen ist das jetzt schwer zu sagen, weil wir nicht wissen, wie Deine Datei *genau* aufgebaut ist. Aber ich versuche mal Folgendes (ungetestet):

Code: Alles auswählen

fname = 'scaffolddna'
seqdata = list()
with open(fname) as seqfile:
   for line in seqfile:
      seqdata.extend(list(line)) 
print seqdata # falls Du Python 3.x nutzt: print(seqdata)
Ich bin mir aber fast sicher, daß Du das gar nicht möchtest: Bei Sequenzdaten ist es meist besser sie als einen String zu haben. Außerdem würde ich Dir nicht raten das Rad neu zu erfinden: biopython dürfte viele Dinge schon können, die Du erst mühsam coden müsstest.

HTH
Christian
Oben hab ich ja geschrieben, wie die Datei aussieht. Biopython kannte ich noch nicht, werd ich mir gleich mal ansehen, danke für den Link. Auch was du vorschlägts, versuch ich mal nachzuvollziehen. Ich möchte nicht die komplette Sequenz als einen String, sondern schon jeden einzelnen Buchstaben.

Danke auf jeden Fall, ich versuchs mal weiter!!
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

cocolino hat geschrieben:Oben hab ich ja geschrieben, wie die Datei aussieht.
Sequenzfiles haben üblicherweise irgendeine Form von Annotation. *Ein* einzelner String ohne Umbrüche ist aber so was von ungewöhnlich, daß ich das erst nicht geglaubt habe. In dem Fall kannst Du "f.read()" eigentlich lassen - abgesehen davon, daß Sequenzen manches Mal extrem lang sind und nackte Strings wenig passende Funktionalität fürs Sequenzhandling bieten.
cocolino hat geschrieben:Ich möchte nicht die komplette Sequenz als einen String, sondern schon jeden einzelnen Buchstaben.
Warum? Willst Du etwa über die Buchstaben iterieren können?
BlackJack

@cocolino: Ich meinte ganz explizit die Dokumentation von list().

Warum genau möchtest Du denn eine Liste haben? `str` ist genau wie `list` ein Sequenztyp. An die einzelnen Buchstaben kommt man genau mit den selben Mitteln. Nur verändern kann man Zeichenketten nicht.
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

CM hat geschrieben:Warum? Willst Du etwa über die Buchstaben iterieren können?
Meine Sequenz (natürlich länger, knapp 8000Basen) muss an bestimmten Stellen crossovers haben und ich muss mit Hilfe des Programms die entsprechenden Gegenstränge berechnen. Dafür muss ich natürlich für jede Base festlegen, ob sie einfach "mittendrin" liegt oder an einem crossover liegt.

Ich versuch mal zu erklären, wie ich das verstanden habe (als Kommentar im Code). Leider ist das Program eben nicht vollständig, die einfachen Teile fehlen wohl, aber für mich als Anfänger ist das halt schwierig. Hier in meiner Vorlage wird zuerst ein virtueller Strang als liste aus '.' erstellt.

Code: Alles auswählen

vstrands=[['.' for i in range (1300)] for j in range (6)] #erstellt eine Liste aus 6 Listen mit je 1300 Indices, alle als string'.'

currentHelix=4
currentBase=19#definiert den Startpunkt, also in Helix 4, Base 19, Frage: woran erkennt man,welche Liste für helix steht und welche für Base?, fehlt da noch was? Oder erfolgt die Zuweisung unten im nächsten Absatz?

scaffoldSequenceList.reverse() #ich soll die Liste umdrehen, aber die hab ich ja noch gar nicht, dass soll die Liste aus den Buchstaben sein, da war eben die Frage, wie bekomme ich die her?
while len(scaffoldSequenceList)>0: #solange noch Elemente in der Liste sind, Schleife ausführen
       vstrand[currentHelix][currentBase]=scaffoldSequenceList.pop() #hierZuordnung, welche Liste helix und welche Base? gleichzeitig wird der letze Wert der liste scaffoldSequenceList zugeordnet, also erfolgt eine Zuordnung der Kombination Helix, Base zu einem Buchstaben
       [x,xx,nextHelix,nextBase]=scaff[currentHelix][currentBase]#bin nicht sicher, aber wird eine Liste als Variablenname verwendet und ihr eine neue Liste zugeordnet? was genau bewirkt das?
       currentHelix=nextHelix
       currentBase=nextBase#hier wird praktisch zu den nächsten Werten gerutscht, Schleife von vorne mit nächsten Werten
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

BlackJack hat geschrieben:@cocolino: Ich meinte ganz explizit die Dokumentation von list().

Warum genau möchtest Du denn eine Liste haben? `str` ist genau wie `list` ein Sequenztyp. An die einzelnen Buchstaben kommt man genau mit den selben Mitteln. Nur verändern kann man Zeichenketten nicht.
Danke! Ich hatte nur im Inhaltverzeichnis das zu Listen angesehen, über die Built-in Functions bin ich als Begriff daher nicht gestolpert. Ich glaube, da könnte das richtige dabei sein.
Was ich damit machen möchte, hab ich oben grad geschrieben. Ich schau mal nach, ob ich jetzt weiterkomme! :oops:
BlackJack

@cocolino: Der Quelltext sieht teilweise etwas komisch aus. `vstrands` könnte man etwas effizienter schreiben in dem man die innere „list comprehension” (LC) durch eine Multiplikation einer Liste mit '.' als einem Element ersetzt. Dann muss in der innderen LC nicht tatsächlich eine Schleife in Python-Bytecode 1300 mal durchlaufen werden. Welche Python-Version verwendest Du denn? Falls 2.x würde ich `xrange()` anstelle von `range()` verwenden.

Was da mit `scaffoldSequenceList` gemacht wird, sieht abenteuerlich aus. Man braucht eine Liste, die wird umgedreht, und dann wird jedes Element von hinten entfernt. Also eigentlich wird die Zeichenkette von vorne zeichenweise abgearbeitet. *Das* geht aber viel einfacher mit einer ``for``-Schleife über die Zeichenkette.

Auf der linken Seite einer Zuweisung eine Liste zu schreiben geht zwar, ist aber ungewöhnlich. Normalerweise sieht man dort ein Tupel. Was das bewirkt, sollte man nach durcharbeiten des Tutorials wissen.

`nextHelix` und `nextBase` scheinen mir überflüssig zu sein. Was `currentHelix` und `currentBase` jeweils beschreiben sollte zum einen aus dem Namen und dann aus der Verwendung eigentlich klar werden. Spiel einfach mal ein wenig mit Listen und verschachtelten Listen in einer Python-Shell und beobachte was der Indexoperator bewirkt beziehungsweise worauf der sich bezieht.

Vom Stil her hält sich der Quelltext nicht an PEP 8 -- Style Guide for Python Code. Das betrifft hauptsächlich die Namen und die Leerzeichen.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Zusätzlich zu BJ Fragen und Anmerkungen:

Der Code ist ziemlich unverständlich:
- Was ist "scaff"? Was passiert mit "vstrand"?
- Was heipt "ich soll"? Willst Du sagen, daß das Hausaufgaben sind?
- Was sind "Helix" und "Base"? Kontext?
- Woher kommen die Startwerte?
- Wer gibt so etwas wie

Code: Alles auswählen

while len(scaffoldSequenceList)>0:
vor? Bist Du selber auf die Idee gekommen, so sollte man eine Schleife in Python angehen? (Tipp: Du kannst ohne Weiteres direkt über einen String oder eine Liste iterieren. Damit würde das .pop() entfallen.)
- der CamelCase ist in Python eher unüblich. *hüstel* siehe BJ-Hinweis auf PEP 8
- etc.

Code: Alles auswählen

>>> seq = 'actg'
>>> seq.upper()[::-1]
'GTCA'
>>> for base in seq.upper()[::-1]: print base
... 
G
T
C
A
Alldieweil das [::-1] ist vielleicht nicht die beste Idee bei sehr langen Sequenzen (~ eurkaryotisches Chromosom), aber das weiß ich nicht genau.
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

Hej ihr zwei!

Wow! Ich bin erst mal totalüberfordert, aber das wird schon noch! Vielleicht noch kurz zum Hintergrund: Nein, das sind keine Hausaufgaben, aus Zer zeit bin ich schon lange raus;)
Ich ab einfach ne neue Stelle an der Uni angetreten (Postdoc) und da wird DNA-Origami gemacht. Eigentlich bin ich Chemikerin/Biochemikerin und bis letze Woche hatte ich mit Programmieren nix am Hut, mal abgesehen von 2 Monaten Mathe in der 9.Klasse in denen ich mich mit TurboPascal eher schlecht als recht rumgeschlagen habe. Aber das liegt jetzt auch schon über 15Jahre zurück.
Ich soll hier auch Biochemie machen (also das, was ich kann), aber ein Teil der Gruppe programmiert und es schadet ja nie was neues zu lernen. Deshalb versuch ich gerad so ein Übungsblatt durchzuarbeiten und wenigstens nachzuvollziehen, was da gemacht wird. Der Code ist kopiert, nur die Kommentare sind von mir. Die Fragen, die ihr mir stellt, stell ich mir auch grade und noch viele mehr! Und manche der Fragen versteh ich nicht mal. Aber ich werde jetzt mal versuchen schrittweise da dran zu gehen, ich muss das ja nicht morgen alles können.
Ihr habt mir trotzdem schon geholfen, so ein zwei Schritte bin ich jetzt glaub ich schon weiter.

Ich meld mich sicher mal wieder und werd mich jetzt mal weiter einarbeiten!

Viele Grüße
BlackJack

@cocolino: Hier ist mal so zum Vergleich das was der gezeigte Quelltext gemacht hat in „pythonischer”:

Code: Alles auswählen

vstrands = [['.'] * 1300 for _ in xrange(6)]

helix_index, base_index = 4, 19

for base in scaffold_sequence:
    vstrand[helix_index][base_index] = base
    _, _, helix_index, base_index = scaff[helix_index][base_index]
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

Danke BlackJack!

Gebt mir etwas Zeit, ich muss mich da wirklich Zeichen für Zeichen durcharbeiten!
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Toi, toi, toi.

Vielleicht hilft es im Interpreter die Variablen nach jedem Schritt mal auszugeben. (Wobei zu empfehlen ist vstrands und die Sequenz kurz zu halten, sonst verliert man ja die Übersicht.) Und vielleicht ist es bei Anfängern (sorry, das soll nicht von oben herab klingen) gut zu wissen, daß "_" einfach für einen Platzhalter steht, der syntaktisch hingehört, aber sonst nicht weiter verwendet wird (Du machst ja nichts mit den Zahlen, die da herauskommen). Jedenfalls war das bei Leuten, denen ich's mal erklärte wichtig.

Und das Suchstichwort wäre "tuple unpacking", wenn Du Dich fragst, was "x, y = 1, 2" oder so soll.

Wenn Deine Gruppe tatsächlich so programmiert sollten die mal 'nen Kurs machen - was Du natürlich nicht sagen kannst. ;-)

Gruß,
Christian
cocolino
User
Beiträge: 7
Registriert: Dienstag 16. August 2011, 09:42

Danke, CM!

Du darfst mich gerne als Anfämger bezeichnen, wahrscheinlich bin ich noch nicht mal das! :shock:
Das mit eine Zeile eingeben, dann ausgeben hab ich mir schon gedacht und auch schon angefangen. Ich geb das mal mit einer kurzen Sequenz (also 10 Basen, müssen ja nicht gleich 8000 sein). Danke euch schon mal, ich lern das schon noch!

Und ja, sieht wohl so aus, als wenn die hier so wüst (?) programmieren, ich kann das nicht beurteilen. Aber vielleicht zur Verteidigung, das sind alle keine Informatiker, sondern Naturwissenschaftler.... :mrgreen:
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

cocolino hat geschrieben:Aber vielleicht zur Verteidigung, das sind alle keine Informatiker, sondern Naturwissenschaftler.... :mrgreen:
Das ist keine Entschuldigung ;-) (wobei ich mich gestern auch wieder geärgert habe, daß mein el. Laborbuch nicht ausreichend Auskunft geben konnte :oops: ). Aber das Problem ist erkannt und es gibt Greg Wilsons Software Carpentry Kurs für Wissenschaftler, die (mit Python) programmieren möchten.
Antworten