Zeilen kuerzen

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.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Ich veruche jede Zeile dieser Datei zu kuerzen wenn die Werte in dieser Zeile kleiner sind als 79 (limit). Wenn die gekuerzte Zeile kuerzer ist als 30 (minLen) ist dann soll die ganze Zeile geloescht werden.

Code: Alles auswählen

83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66,66,66,66
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66
66,66,66,66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,80,80,80,83
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83
65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,66,66,66,66,66,66,66,66,66,66,66,66,66,66
83,83,83,65,65,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
97,97,97,97,97,97,97,97,97,97,97,86,82,69,91,85,85,88,91,72,91,93,91,97,97,97,97,97,95,91,77,69,77,95,95,93
79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79
Ich habe diesen Code geschrieben

Code: Alles auswählen

import sys
inputFile = open(sys.argv[1], 'r')


def findBiggestLength(integ):
  i = 0
  startPosFound = False

  startPos = 0
  endPos = 0
  biggestSeqLength = 0
  limit = 79
  minLen = 30
  length = len(integ)
  while i < length:

    if (integ[i] >= limit) and (startPosFound == False):
      startPos = i
      startPosFound = True
    elif (integ[i] < limit):
      startPosFound = False
      biggestSeqLength = i - startPos + 1
      if biggestSeqLength >= minLen:
        endPos = i - 1
    i += 1
  return (startPos, endPos+1)



for line in inputFile:
  line = line.rstrip()
  line = line.split(",")
  (startPos, endPos) = findBiggestLength(line)
  print line[startPos:endPos]
aber leider funktioniert dieser Code nicht.

Was mache ich falsch?

Viele Gruesse
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hier mein Vorschlag:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys


def shorten(row):
    values = map(int, row.strip().split(","))
    new_row = [val for val in values if val < 79]
    if len(new_row) > 29:
        return ",".join(map(str, new_row))


def main():
    with open(sys.argv[1], "r") as infile:
        rows = infile.readlines()
    res = "\n".join(row for row in map(shorten, rows) if row)
    # hier dann ggf. wegschreiben
    print res


if __name__ == "__main__":
    main()
Ich hoffe ich habe Deine Angaben richtig interpretiert (die Beschreibung des Problems war doch recht dürftig imho).
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Genau, "funktioniert nicht" ist irgendwie keine funktionierende Problembeschreibung ;)

Das CSV Modul könnte dir auch noch helfen, deine Datei zu parsen.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

@mit: Hat dir schonmal jemand gesagt, dass dein Code sehr unpythonisch ist?

Wenn du ``while`` benutzt wie in Zeile 16, bietet sich fast immer eine for-Schleife an. Alternativ sind ``list comprehension`` oder ``map()`` nützliche Kurzformen. Initialisierung wie in Zeile 7 bis 15 sind auch sehr ungewöhnlich und am besten zu vermeiden. Schau dir am besten auch PEP 8, den Style Guide für Python, an. Das macht es für Dritte einfacher deinen Code zu verstehen.

Grüße
Gerrit
Zuletzt geändert von gkuhl am Dienstag 9. März 2010, 11:37, insgesamt 1-mal geändert.
BlackJack

@mit: Weil's anscheinend noch keiner meiner Vorredner explizit gesagt hat: Du vergleichst Äpfel mir Birnen, äh, ich meine ganze Zahlen mit Zeichenketten.

Code: Alles auswählen

In [4]: '42' < 79
Out[4]: False
@Hyperion: Warum `readlines()`? Man hätte `shorten()` doch auch auf `infile` `map()`\en können.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben: @Hyperion: Warum `readlines()`? Man hätte `shorten()` doch auch auf `infile` `map()`\en können.
Tja... da kann ich nur sagen, dass Du vollkommen Recht hast :-)
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Leider programmiere ich in Python noch wie mit Java.

@Hyperion: Danke für dein Code, aber leider funktioniert es nicht ganz denn ich bekomme diese Ausgabe:

Code: Alles auswählen

65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65
68,77,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
68,77,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
Z.B. diese Zeile
83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
müsst nach dem kürzen wie folgt aussehen:
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83

Leider alle meine Lösungen sind fehlgeschlagen.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Was daran liegt, dass du dein Problem noch immer nicht vollständig beschrieben hast. Wenn ich dich jetzt richtig verstehe, musst du Hyperions Code etwas erweitern um dein Problem zu lösen.

Falls du Hilfe brauchst solltest du dein Problem nochmal vollständig beschreiben.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

mit hat geschrieben: Z.B. diese Zeile
83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
müsst nach dem kürzen wie folgt aussehen:
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
Wie können da denn Werte von >= 79 drin stehen? Du wolltest doch nur alle diejnigen haben, die < 79 sind?!?

Du musst dann eben noch mal genauer beschreiben, was Du haben willst... :roll:
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Tut mir Leid ich habe ein Fehler gemacht es müsste >= 79 sein. Habe den Code von Hyperion geändert und bekomme jetzt diese Ausgabe:

Code: Alles auswählen

83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,80,80,80,83
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83
83,83,83,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,83,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,83,83
97,97,97,97,97,97,97,97,97,97,97,86,82,91,85,85,88,91,91,93,91,97,97,97,97,97,95,91,95,95,93
79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79
Dieser Code löscht alle Werte die kleiner sind als 79 und dann prüft ob die gekürzte Sequenz > 29 ist wenn nicht wird sie gelöscht.

Mein Problem ist einwenig anders.
Z.B.

Code: Alles auswählen

83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
Die ersten beiden 83 Werte sind gut, aber der nächste Wert ist 65 und deshalb müssen die ersten drei Werte gelöscht werden. Die neue start Postion ist 83 (nach 65). Alle Zahlen sind bis zu der viert letzten Positon gut dann kommt 65 (also ein schlechter Wert), d.h. die eine Postion vorher (83) ist Ende der Sequence. Aber die Zeile ist noch nicht zu Ende, weil es noch 2 x 83 gibt (gute Werte).

Die erste Sequence (83,80,80,...,80,80,83) sollte übrig bleiben da diese länger ist als 29 und die letzten 2 X 83 Werte sind kleiner als 29 und müssen gelöscht werden.

Ergebnis müsste wie folgt aussehen:

Code: Alles auswählen

83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83 
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mit hat geschrieben: Mein Problem ist einwenig anders.
Z.B.

Code: Alles auswählen

83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
Die ersten beiden 83 Werte sind gut, aber der nächste Wert ist 65 und deshalb die ersten drei Werte löschen. Die neue start Postion ist 83 (nach 65). Alle Zahlen sind aber in der dritt letzten Positon ist 65 (also ein schlechter Wert), d.h. die eine Postion vorher (83) ist Ende der Sequence. Aber die Zeile ist noch nicht zu Ende, weil es noch 2 x 83 gibt (gute Werte).
<tilt>syntax error</tilt>

Ein Versuch der Interpretation: Du hast eine Liste von Zahlen. Du möchtest aus dieser Liste von hinten gesehen möglichst viele Zahlen sammeln. Du hörst mit dem Sammeln auf, sobald du auf eine Zahl triffst die kleiner als 69 ist.

Korrekt?

edit: Hmmm, das scheint nicht korrekt zu sein, weil im Beispiel mal links und mal rechts abgeschnitten wird. Das Regelwerk dafür bleibt allerdings unklar.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

/me hat geschrieben:
Ein Versuch der Interpretation: Du hast eine Liste von Zahlen. Du möchtest aus dieser Liste von hinten gesehen möglichst viele Zahlen sammeln. Du hörst mit dem Sammeln auf, sobald du auf eine Zahl triffst die kleiner als 69 ist.

Korrekt?

edit: Hmmm, das scheint nicht korrekt zu sein, weil im Beispiel mal links und mal rechts abgeschnitten wird. Das Regelwerk dafür bleibt allerdings unklar.
Ich vermute es so:
Er sucht Sequenzen S mit S(a) >= 79 für alle a und len(S)>=29
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Eigentlich möchte ich von links nach recht vorgehen. Wenn ein Wert kleiner ist als 79 muss ich die Anzahl an gelesenen Werte bis dahin bestimmen und wenn diese Anzahl > 29 ist möchte ich alle diese Werte beinhalten. Sollte diese Sequenz aber < 29 sein dann gehe ich Postion weiter und wenn dieser neue Wert >= 79 ist ist dies mein neuer start Wert und ich versuche mit den übrigen Werten eine Sequenz zu bilden die größer als 29 ist.

Wenn ich .robert richtig verstanden habe ist es was ich suche.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ahso... jetzt habe ich es verstanden! Spielen die Zeilen da eine Rolle? Oder soll das Zeilenübergreifend sein? (Ich frage das lieber noch mal nach!)
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Jeder Zeile wird nur für sich betrachtet. Zwischen den Zeilen gibt es keine Verbindung.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Das prinzip mal eben in ganz scheiße und oberflächlich zusammengehackt:

Code: Alles auswählen

in_data = """
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66,66,66,66\n
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66\n
66,66,66,66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83\n
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,80,80,80,83\n
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83\n
65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65\n
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,66,66,66,66,66,66,66,66,66,66,66,66,66,66\n
83,83,83,65,65,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83\n
83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83\n
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66\n
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66\n
97,97,97,97,97,97,97,97,97,97,97,86,82,69,91,85,85,88,91,72,91,93,91,97,97,97,97,97,95,91,77,69,77,95,95,93\n
79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79\n
"""
in_data = in_data.split('\n')

out_data = []

for line in in_data:
    line = line.split(',')
    b = []
    for i in line:
        if i and int(i)>= 79:
            b.append(i)
        elif len(b)>=29:
            out_data.append(b)
            b = []

print out_dat
das schön zu machen ist deine aufgabe
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

So als Schnellschuss:

Code: Alles auswählen

def shorten(row, vallimit=79, rowlimit=29):
    values = map(int, row.strip().split(","))
    res = []
    tmp = []
    for val in values:
        if val > vallimit:
            tmp.append(val)
        else:
            if len(tmp) > rowlimit:
                res.extend(tmp)
            tmp = []
    if res:
        return ",".join(map(str, res))
Evtl. könnte man das mit itertools eleganter lösen. Aber dafür hatte ich grad keine Zeit :-)

Ist jetzt nur für eine Zeile; das einzubauen überlasse ich mal dem OP.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@.robert: Bei Deiner Lösung entstehen neue Zeilen; ich glaube das war nicht gewünscht. (Daher bei mir 2 Listen)
Ronnie
User
Beiträge: 73
Registriert: Sonntag 21. März 2004, 17:44

So wie ich es verstanden habe: kein Werte kleiner 79 und min. 30 Werte je Zeile:

Code: Alles auswählen

>>> lines = """83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66,66,66,66
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,66,66,66
66,66,66,66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
66,66,66,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,80,80,80,83
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83
65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65
83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,66,66,66,66,66,66,66,66,66,66,66,66,66,66
83,83,83,65,65,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83
83,83,65,83,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,80,80,80,80,80,80,80,83,65,83,83
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
68,77,88,89,88,88,88,89,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
97,97,97,97,97,97,97,97,97,97,97,86,82,69,91,85,85,88,91,72,91,93,91,97,97,97,97,97,95,91,77,69,77,95,95,93
79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79"""
>>> limit = 79
>>> minlen = 30
>>> filtered = [items for items in [[int(v) for v in line.split(",") if int(v) >= limit] for line in lines.split("\n") if len(line) > 0] if len(items) > minlen]
Achtung: User ist ein Python-Lehrling!
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

@Hyperion: meine "Lösung" ist erst mal nur ein simpler Parser, der Sequenzen mit den gegebenen Bedingungen erkennt und ausgibt.
Ich würde die dann in eine neue Datei schreiben, denke ich, dann gibt es kein Problem mit neuen Zeilen ;-)
Antworten