Lösche letztes Element der Zeil, wenn...

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
anfenger
User
Beiträge: 2
Registriert: Dienstag 17. März 2009, 21:56

Einen schönen guten Abend,

ich komme mit diesem bestimmt einfach lösbaren Problem gerade nicht weiter. Vielleicht kann mit einer von euch kurz helfen, das wäre wirklich super!
Hier das Problemchen:
Ich habe ein großes File, indem in jeder Zeile ungefähr die Struktur vorkommt. Beispiel:
79813: [543, [123,456,789], [823,345,756], [2345]]
79813: [543, [123,456,789], [823,345,756], [2345,2345]]

Nun möchte ich, wenn in einer Klammer [...] nicht die gleiche Komma-Anzahl wie in den anderen KLammern vorkommt, diese Klammer löschen.
Für obiges Beispiel sollte das Ergebnis folgend aussehen:
79813: [543, [123,456,789], [823,345,756]]
79813: [543, [123,456,789], [823,345,756]]

Da in dem Element [2345] nicht gleich viele Kommas (2), wie in den vorherigen Klammern vorkommt, möchte ich ', [2345]' löschen.
Ebenso für das 2. Beispiel: Da in dem Element [2345,2345] nicht gleich viele Kommas (2), wie in den vorherigen Klammern vorkommt, möchte ich ', [2345,2345]' löschen.

Vielen Dank für Tipps und Vorschläge!
problembär

Du kannst Deine Aufgabenstellung doch schon beschreiben.
Warum kannst Du es denn jetzt nicht in Code umsetzen?

Zeig doch mal, was Du bisher hast.

Gruß
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

So einfach ist das gar nicht mal ...
Wenn die Zeilen immer genau so aussehen, wie sie das jetzt tun, ist das aber eigentlich auf Basis von str.replace, str.count, str.split, str.index und len möglich ;)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sofern es keine Funktion dafür gibt: Bau eine Schleife, in der du die jeweiligen Elemente der beiden Listen auf ihre Länge hin vergleichst. Dabei zählst du den Index mit (`enumerate()`) und schmeißt bei unterschiedlichen Längen die beiden Elemente mit dem aktuellen Index raus (`pop()`).
Nocta hat geschrieben:So einfach ist das gar nicht mal ...
Wenn die Zeilen immer genau so aussehen, wie sie das jetzt tun, ist das aber eigentlich auf Basis von str.replace, str.count, str.split, str.index und len möglich ;)
Wo siehst du da Strings?

Achso, ich hatte das jetzt für ein Dictionary gehalten...
Zuletzt geändert von snafu am Dienstag 17. März 2009, 23:03, insgesamt 1-mal geändert.
anfenger
User
Beiträge: 2
Registriert: Dienstag 17. März 2009, 21:56

problembär hat geschrieben:Du kannst Deine Aufgabenstellung doch schon beschreiben.
Warum kannst Du es denn jetzt nicht in Code umsetzen?

Zeig doch mal, was Du bisher hast.

Gruß
hi,

also ich habs probiert mit 1.):

Code: Alles auswählen

            
            teil = s.split(", ") #s ist hier die jeweilige zeile
            If teil[-1].count(',')==0:
                del teil[-1]
            If teil[-1].count(',')!=teil[1].count(','):
                del teil[-1]
            if teil[-2].count(',')==0:
                del teil[-2]
und auch mit 2.) regulären ausdrücken:

Code: Alles auswählen

   
p = re.compile('((\,)(\s?)(\[)(\d*)(\,*)(\d+)(\,*)(\d*)(\]))')
   for s in textfile: 
   f = p.sub(']', s) #s ist hier wieder die jeweilige zeile 
Bringt bisher nicht das gewünschte Ergebnis... :(
BlackJack

@snafu: Das sind laut Beschreibung vom OP Zeilen in einer Textdatei -- also Zeichenketten.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Das Textformat sollte am besten einheitlich sein. Also so, das die du immer ", " als Trenner hast und da keine unnützen Zeichen rumfliegen. Dann könntest du mit dem Ausdruck

Code: Alles auswählen

s[s.index("[") + 1:-(len(s) - s.rindex("]"))].split(", ")

Wirft einen ValueError wenn es keine passenden Klammern gibt. Einen solchen String zu einer Liste umbauen. Das kannst du dann noch beliebig rekursiv anwenden, ala

Code: Alles auswählen

def to_list(s):
    return [to_list(sub_s) for sub_s in <ausdruck>]
Am Ende müsstest du in der entstehenden Listen mit len() arbeiten um die Länge zu ermitteln und das gemäss deinen Bedingungen anzupassen. Und du musst noch darauf achten, das ein substring richtig behandelt wird wenn er keine Klammern enthält, dh ValueError abfangen.

Um daraus wieder einen String zu machen kannst du repr() benutzen.

Dann hast du dir aber zunutze gemacht, das Listen genauso dargestellt werden wie deine Strings (sofern ", " als Trenner gilt). Und generell sieht das ein wenig unsauber aus.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Die arme YAML Datei :/

Lese die Datei Zeile für Zeile ein und lasse das YAML parsen und pack jede Zeile in eine Liste. Dann mach weiter mit dem was snafu geraten hat.
BlackJack

Also ich würd's ja als JSON parsen, das ist ab 2.6 wenigstens in der Standardbibliothek.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

DasIch hat geschrieben:Lese die Datei Zeile für Zeile ein und lasse das YAML parsen und pack jede Zeile in eine Liste. Dann mach weiter mit dem was snafu geraten hat.
Ich hatte schon etwas mit `split(': ')` und `eval()` (für den Teil mit der Liste) gebastelt. Fand ich aber dann doch zu unschön, um es zu posten, vor allem weil man am Ende ja auch wieder alles zu einem String machen muss.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

An YAML / JSON hatte ich auch gedacht, aber solche Formate sehen immer nach "fremdbestimmt" aus, und das muss nunmal kein komplett gültiges Yaml sein (Außerdem kommt 78913 als Dictionary Key zweimal vor, wenn man das als Yaml auffassen würde und das nicht irgendwas Triviales ist oder sö). Würde er das Format für eine eigene Anwendung zusammentipseln wollen wäre er sicherlich schon auf YAML usw gestossen.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Zeilenweise JSON Parsen.
Antworten