Seite 1 von 1

Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 10:55
von mampfgnom
Hallo.

Ich bin Python Neuling und stehe vor einem kleinen Problem beim Einlesen einer Datei. Das Einlesen der Zeilen ist kein Problem allerdings muss ich die jeweilige Zeile aufteilen und Variablen zuweisen und da klemmt es ein bisschen. Hier ein Beispiel:

Code: Alles auswählen

s = '1, 2, 3, [12, 13,14]'
Ich will diesen String jetzt gerne so aufteilen dass ich 3 Integer Variablen erhalte und eine Liste. Bisher kannte ich nur das Vorgehen.

Code: Alles auswählen

var1,var2,var3,var4 = s.strip(' ').split(',')
Das ist aber ein naiver Versuch den hinteren Teil in den eckigen Klammern in eine einzige Variable zu speichern. Nach ein wenig Recherche habe ich mir das hier zusammen gebastelt:

Code: Alles auswählen

links = s.rfind('[')
rechts = s.rfind(']')
liste = s[links+1:rechts].split(',')
for i in range(len(liste)):
	liste[i] = int(liste[i])
var1, var2, var3 = s[:links-1].strip(' ').split(',')
Das scheint auch zu funktionieren. Ich weiß nur nicht, ob das allgemeingültig und stabil ist. Kennt ihr vielleicht eine bessere Lösung oder ist das hier schon okay?

Grüße

Mampfgnom

P.S.: Ich hoffe das ist das richtige Forum

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 11:15
von Hyperion
Man könnte es so machen:

Code: Alles auswählen

import json
a, b, c, d = (item for item in json.loads('[%s]' % '1, 2, 3, [12, 13,14]'))
print(a, b, c, d)
:mrgreen:

Aber mal im Ernst: Woher stammen denn diese Daten? Evtl. kann man das Format wirklich *direkt* auf JSON (o.ä.) umstellen? Das erschiene mir sinnvoller. Wenn nicht, ist das irgend ein anderes Standardformat? Wenn ja, gibt es dafür ggf. schon einen eigenen Parser?

Wenn das alles nicht geht, dann braucht man def. einen Gesamtüberblick über die Grammatik des ganzen. Dann kann man einen robusten Parser dafür schreiben.

Aber noch etwas: Wozu willst Du die Werte an separate Namen binden? Evtl. ist das an sich schon unnötig. Aber ohne den Kontext kann man dazu wenig sagen...

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 11:47
von mampfgnom
Hallo und Danke für die Antwort.

Du hast mich ehrlich gesagt ein wenig erschlagen mit deiner Antwort, wie gesagt ich bin Neuling. Ich versuche mal deine Fragen zu beantworten:

Die Daten stammen von mir selber und entstehen im Laufe eines Rechenzyklus. Das Format ist fest und lautet:

int, int, int, list

Die Anzahl der Elemente in der Liste variiert allerdings. Ich denke einen eigenen Parser brauch man dafür nicht. Deine Variante sieht sehr schön kompakt aus, allerdings habe ich nur Python 2.4.3.

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 11:53
von Hyperion
Wenn die Daten von Dir selber stammen, dann wähle doch für das Serialisieren bereits ein gescheites Format! JSON fiel mir jetzt schnell ein, es gibt ja noch zig anderen, die gingen. Für 2.4 muss man iirc das `simplejson`-Modul nachinstallieren, da dieses dann erst ab 2.5 als Modul in die Standard-Lib aufgenommen wurde.

Darf man fragen, wieso Du mit so einer alten Version von Python arbeitest? Wenn es keine zwingenden Gründe gibt, steig auf jeden Fall auf die aktuelle 2.7er um!

Du kannst auch mal gucken, ob Dir `pickle` reichen würde. Wenn Du die Datei nicht extern lesen / schreiben willst, ginge das sicherlich auch.

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 12:19
von BlackJack
@Hyperion: Wozu ist der Generatorausdruck gut?

Code: Alles auswählen

In [215]: json.loads('[%s]' % '1, 2, 3, [12, 13,14]')
Out[215]: [1, 2, 3, [12, 13, 14]]

In [216]: a, b, c, d = json.loads('[%s]' % '1, 2, 3, [12, 13,14]')

In [217]: a
Out[217]: 1

In [218]: b
Out[218]: 2

In [219]: c
Out[219]: 3

In [220]: d
Out[220]: [12, 13, 14]

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 12:24
von mampfgnom
Ich arbeite in der Universität an meiner Diplomarbeit und auf dem Rechner, der mir zu Verfügung gestellt wird, ist nur das alte Python installiert. Ich werde aber mal beim Systemadministrator anfragen, ob ich die neue Version aufgespielt kriegen kann.

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 14:22
von Kebap
Na gut, Fremdrechner / Systemadministrator könnte schon zu "zwingenden Gründen" gegen ein Update der Pythonversion zählen. Gibt es aber auch zwingende Gründe, wieso du die Daten unbedingt in dieser Form speicherst? Dadurch entstehen ja erst die Probleme beim Wieder-Einlesen. Wenn du tatsächlich beide Seiten dieser deiner dann ja internen Schnittstelle beeinflussen kannst, dann würde ich die anderen unterstützen, und nicht mehr viel Zeit mit String-Manipulationen vertrödeln, sondern direkt ein vernünftige Format wählen. Schnittstellen nerven, sollte man vermeiden. :mrgreen:

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 15:25
von Hyperion
BlackJack hat geschrieben:@Hyperion: Wozu ist der Generatorausdruck gut?
Äh... der sah so schnuckelig aus :oops: Man sollte Dinge niemals so schnell posten, wenn man erst eine andere Idee hatte... ich hoffe die Ausrede reicht :-)

@Kebap: Ich hoffe der OP hat verstanden, dass er auch schon beim *Serialisieren* auf eine entsprechende Lib zurückgreifen soll ;-) Bei `pickle` hätte ich Magenschmerzen, dass das Erzeugte mit einem neueren Python nicht mehr gelesen werden kann - oder irre ich hier? Was bleibt sonst so? `shelve`, `marshall`? JSON erscheint mit von der Struktur her erst einmal am natürlichsten.

Man kann aufgrund der Unerfahrenheit des OP natürlich generell mal nachfragen, ob eine Serialisierung wirklich erforderlich ist...

Re: Liste in einem String erkennen

Verfasst: Mittwoch 6. Juni 2012, 16:29
von BlackJack
@Hyperion: Pickles sind über Python-Versionen hinweg lesbar (zumindest rückwärtskompatibel). Das Problem was man sich da schnell einhandeln kann ist eher das sich die Programme mit denen man sie geschrieben hat, weiter entwickeln und wenn man sich nicht auf Python-Grunddatentypen beschränkt, kann es sein dass die gespeicherten Daten und Namen nicht mehr zum Programm passen. Wenn man also etwas umbenennt oder in ein anderes Modul verschiebt, oder bei Klassen Attribute hinzufügt oder weglässt, passen die Daten im Pickle nicht mehr und können zu Problemen führen.

`shelve` benutzt für die Werte selbst `pickle`. Ist also keine Lösung wenn man `pickle` vermeiden möchte.

@mampfgnom: Ebenfalls eine einfache Lösung, die ohne Zusatzmodule auskommt, wäre es nicht einfach so Python-Listen mit `str()` oder ähnlichem in Zeichenketten umzuwandeln, sondern dass explizit selbst zu machen und dann für die beiden „Ebenen” verschiedene Trennzeichen zu verwenden. Also Beispielsweise: ``'1,2,3,12;13;14'``. Das lässt sich in zwei Schritten einfach und eindeutig mit `slit()`-Aufrufen trennen.

Ein Standardformat wie JSON wäre aber meiner Meinung nach immer besser, denn dafür gibt es für die verschiedensten Programmiersprachen robuste Parser und auch Generatoren.

Re: Liste in einem String erkennen

Verfasst: Freitag 8. Juni 2012, 08:56
von mampfgnom
Ich war gestern krank, weswegen ich mich erst heute melde.

Das mit dem Pythonupdate wird wohl nichts. Der Systemadministrator macht keine Anstalten was zu ändern^^

@BlackJack: Die Idee mit den Kommata und Semikola finde ich gut und werde das so auch mal umsetzen.
Hyperion hat geschrieben: Man kann aufgrund der Unerfahrenheit des OP natürlich generell mal nachfragen, ob eine Serialisierung wirklich erforderlich ist...
Ja ich glaube das ich wirklich nicht erforderlich^^

Also vielen Dank für die Hilfe und die guten Anregungen.

Re: Liste in einem String erkennen

Verfasst: Freitag 8. Juni 2012, 11:17
von Hyperion
mampfgnom hat geschrieben: Das mit dem Pythonupdate wird wohl nichts. Der Systemadministrator macht keine Anstalten was zu ändern^^
Naja, Admins sind idR. eher nicht dafür bekannt, schnell zu agieren ;-) Meiner Erfahrung nach kann man als normaler Studi da wenig bewegen - außer man hat einen persönlichen Draht zu einem Admin. Ansonsten bringt es eher etwas, wenn ein Assistent oder gar Professor Druck macht.
mampfgnom hat geschrieben: @BlackJack: Die Idee mit den Kommata und Semikola finde ich gut und werde das so auch mal umsetzen.
Also doch Serialisierung :-D ?