Textdatei in einzelne Variablen splitten

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
Cyberbroker
User
Beiträge: 16
Registriert: Dienstag 17. November 2009, 22:18

Hey,

ich such ne Möglichkeit wie ich aus einer Datei/Liste mehrer Strings auslesen kann und in verschiedenen Vars speichern kann.

Die Datei ist wie folgt aufgebaut

Code: Alles auswählen

C(=C)CCCCCCC	name1
C(CCCCCC)(C)C	name2
C(CCCCC)(CC)C	name3
C(CCCC)(CCC)C	name4
C(CCCC(C)C)(C)C	name5
C(=C)CCCCCC=C	name6
C(CCCC)(CC)CC	name7
oder wenn ichs als liste lade:

Code: Alles auswählen

>>>linestring=open('Testfile.txt','r').readlines()
['C(=C)CCCCCCC\tname1', 'C(CCCCCC)(C)C\tname2', 'C(CCCCC)(CC)C\tname3', 'C(CCCC)(CCC)C\tname4', 'C(CCCC(C)C)(C)C\tname5', '', 'C(=C)CCCCCC=C\tname6', 'C(CCCC)(CC)CC\tname7']
Was ich brauche ist "NameX" sprich, das was mit dem sperator \t getrennt wird, und dann entsprechend als varX gespeichert werden.

Es einfach nur zu splitten:

Code: Alles auswählen

>>>str=open('testfile.txt','r').read();
>>>print (str.split());
['C(=C)CCCCCCC', 'name1', 'C(CCCCCC)(C)C', 'name2', 'C(CCCCC)(CC)C', 'name3', 'C(CCCC)(CCC)C', 'name4', 'C(CCCC(C)C)(C)C', 'name5', 'C(=C)CCCCCC=C', 'name6', 'C(CCCC)(CC)CC', 'name7']

funktioniert zwar, aber hier weiss ich nich weiter wie ich nur noch die "nameX" vars abrufen kann....

Hoffe ich konnte mein Problem verständlich schildern, und shconmal danke vorab für tips.

Gruß,

René
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ich gehe mal davon aus, dass du die Namen in einer Liste haben möchtest. Dazu liest du die Datei zeilenweise aus und zerlegst dann jede Zeile in ihre Bestandteile.

Code: Alles auswählen

names = []
with open('testfile.txt') as fp:
    for line in fp:
        names.append(line.split()[-1])
print names

# alternativ mit list comprehension
with open('testfile.txt') as fp:
    data = fp.readlines()
    names = [value.split()[-1] for value in data if value]
print names

# noch eine Alternative
with open('testfile.txt') as fp:
    data = fp.read()
    names = data.split()[1::2]
print names
Hier sind jetzt noch keine Sicherungsmaßnahmen eingebaut die dafür sorgen, dass auf ungültige Eingaben passend reagiert wird.

Die Verwendung von with sorgt übrigens dafür, dass die Datei nach Abarbeitung des Blocks geschlossen wird (sofern sie geöffnet werden konnte). Gewöhne dir das beim Umgang mit Dateien direkt an.
Zuletzt geändert von /me am Dienstag 17. Januar 2012, 22:34, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also als erstes: Wie kommt es zu diesem Format? Kannst Du das beeinflussen oder ist das fix vorgegeben? Oder gar von Dir am Ende "erdacht"?

Als nächstes: Du willst nicht wirklich in Python schreiben können:

Code: Alles auswählen

print name1
->
C(=C)CCCCCCC
??? Oder etwa doch?

Wenn ja -> schau Dir mal die grundlegenden Strukturen an, etwa Listen oder Dictionaries!

Ich würde so in der Art vorgehen:

Code: Alles auswählen

In [41]: from StringIO import StringIO

In [42]: data = u"""
C(=C)CCCCCCC   name1
C(CCCCCC)(C)C   name2
C(CCCCC)(CC)C   name3
C(CCCC)(CCC)C   name4
C(CCCC(C)C)(C)C   name5
C(=C)CCCCCC=C   name6
C(CCCC)(CC)CC   name7
"""

In [51]: result = {}

In [53]: f = StringIO(data)

In [54]: for line in f:
   ....:     if line.strip():
   ....:         token, key = line.strip().split()
   ....:         result[key] = token
   ....:         
   ....:         

In [55]: result
Out[55]: 
{u'name1': u'C(=C)CCCCCCC',
 u'name2': u'C(CCCCCC)(C)C',
 u'name3': u'C(CCCCC)(CC)C',
 u'name4': u'C(CCCC)(CCC)C',
 u'name5': u'C(CCCC(C)C)(C)C',
 u'name6': u'C(=C)CCCCCC=C',
 u'name7': u'C(CCCC)(CC)CC'}
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Cyberbroker
User
Beiträge: 16
Registriert: Dienstag 17. November 2009, 22:18

/me hat geschrieben:

Code: Alles auswählen



# noch eine Alternative
with open('testfile.txt') as fp:
    data = fp.read()
    names = data.split()[1::2]
print names
Hier sind jetzt noch keine Sicherungsmaßnahmen eingebaut die dafür sorgen, dass auf ungültige Eingaben passend reagiert wird.

Die Verwendung von with sorgt übrigens dafür, dass die Datei nach Abarbeitung des Blocks geschlossen wird (sofern sie geöffnet werden konnte). Gewöhne dir das beim Umgang mit Dateien direkt an.
Vielen dank. Die alternative oben scheint am besten zu funktionieren.

Code: Alles auswählen

#Laden der Molekelnamen in names
with open('testfile.txt') as fp:
    data = fp.read()
    names = data.split()[1::2]
print (names)


#Abfrage der Molekelname mittels web-based adjlist
import urllib
import urllib.request
import urllib.parse

for i in names:
    a=("http://rmg.mit.edu/adjacencylist/"+i)
    print(a) #Test ob Ausgabe korrekt/wo fehler is.

    
    urllib.request.urlretrieve \
                              (a,i+".txt")
                     
Das klappt jetzt soweit alles sehr gut.
Ich bin ein ziemlicher Python Neuling. Hoffe ich hab in dem Code oben keine groben Schnitzer erlaubt. Falls doch bin ich für jeden Hinweis dankbar.

Nochmal Dank für die schnelle Hilfe.

Gruß,

René
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Cyberbroker hat geschrieben:

Code: Alles auswählen

for i in names:
    a=("http://rmg.mit.edu/adjacencylist/"+i)
    print(a) #Test ob Ausgabe korrekt/wo fehler is.

    
    urllib.request.urlretrieve \
                              (a,i+".txt")
Das klappt jetzt soweit alles sehr gut.
Ich bin ein ziemlicher Python Neuling. Hoffe ich hab in dem Code oben keine groben Schnitzer erlaubt. Falls doch bin ich für jeden Hinweis dankbar.
Python-Neuling? Dann solltest du wissen, dass es einen entscheidenden Unterschied macht ob du Python2 oder Python3 verwendest. Python3 ist an manchen Stellen bewusst nicht abwärtskompatibel. Ich vermute, dass es bei dir Python3 ist, da du print mit Klammern verwendest.

Kurz zum Code: verwende sinnvolle Namen, verwende ab und zu mehr Leerzeichen, verwende Klammern nur wenn sie erforderlich sind und versuche Zeilenfortsetzungen mit Backslash zu vermeiden.


Jetzt erkläre ich das etwas länger:

Code: Alles auswählen

for i in names:
i ist extrem nichtssagend und wird typischerweise als Laufvariable mit numerischem Inhalt in Schleifen verwendet. Als passender würde ich es erachten, wenn der Bezeichner name hieße. Ich weiß, dass das jetzt nur ein kurzes kleines Programm ist, aber warum soll man es nicht von Anfang an ordentlich machen? Sinnvolle Namensgebung hilft ungemein beim Verständnis des Quelltextes. Wir bekommen dann also:

Code: Alles auswählen

for name in names:

Code: Alles auswählen

    a=("http://rmg.mit.edu/adjacencylist/"+i)
Die Klammern braucht man hier nicht. Zudem ist dieses +i hinten nur schwer zu sehen. Hier bietet sich die im Python Style Guide (bitte bei Gelegenheit lesen) empfohlene Verwendung von Leerzeichen an. Zusammen mit der vorherigen Änderung des Bezeichnernamens ergibt sich dann:

Code: Alles auswählen

    url = 'http://rmg.mit.edu/adjacencylist/' + name
Die Verwendung von einfachen Hochkommas statt doppelter macht keinen Unterschied, aber beim Drucken von Quelltext brauche ich mit meiner Methode weniger Toner. :D
Man könnte den String übrigens statt mit dem Plus-Zeichen auch mit format zusammenbauen, aber das möchte ich nicht auch noch direkt erklären.


Code: Alles auswählen

    urllib.request.urlretrieve \
                              (a,i+".txt")
Namen, Leerzeichen, Umbruch:

Code: Alles auswählen

    urllib.request.urlretrieve(url, name + '.txt')

Zum Zeilenumbruch sollte ich dann doch noch ein paar Worte verlieren. Die Verwendung des Backslash als Fortsetzungszeichen ist meiner Meinung nach keine wirklich gute Idee. Es genügt schon ein Leerzeichen dahinter und schon funktioniert das nicht mehr. Im Editor fällt das typischerweise nicht auf, zur Laufzeit dann aber sehr schnell. Hier helfen dann Klammern sehr schön - ja, genau die Klammern die ich dir eben noch ausgeredet habe. Innerhalb von Klammern wird der Befehl fortgesetzt, auch wenn er über mehrere Zeilen geht. Die folgenden Beispiele zeigen wie das aussehen kann.

Code: Alles auswählen

result = (23 +
    42)

result = (
    23

    +
    42
    )
Zum Schluss noch ein Tipp für künftige Höhenflüge mit Python:

Code: Alles auswählen

import antigravity
Cyberbroker
User
Beiträge: 16
Registriert: Dienstag 17. November 2009, 22:18

Vielen Dank. Ja ich nutze Python 3.

hab mir jetzt deine Tipps zu herzen genommen und finds eindeutig einfacher.

Hab mal antigravity importiert, allerdings scheint das aufgrund der derzeitigen SOPA Debatte nicht wie gewöhnlich angezeigt.

Nochmals, danke^^

Gruß

René
Antworten