Textdatei durchsuchen

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

flummi hat geschrieben:Was ist der unterschied zwischen str.index und str.find?
Ok, ich lese mal die Doku für Dich vor:
Doku hat geschrieben: str.index(sub[, start[, end]])
Like find(), but raise ValueError when the substring is not found.
flummi hat geschrieben: Wie funktioniert diese Methode? Was bringt mir der Index? kann ich an einem bestimmten index splitten? wie geht das?
Das sind absolute Basics, die in jedem Tutorial erklärt werden sollten (im offiziellen sind sie es auf jeden Fall ;-) )

Aber weil ich mal lieb bin, zeige ich Dir, wie Du das auch leicht selber hättest rausfinden können (genau dafür nutzt man u.a. Python-Shells!):

Code: Alles auswählen

In [12]: s = "Hallo Welt"

In [13]: s.index("Welt")
Out[13]: 6

In [14]: s[6]
Out[14]: 'W'
flummi hat geschrieben: ich hab mir folgendes gebastelt, diese funktion soll doppelt splitten.
funktioniert allerdings nur für die erste zeile einer hand um die handnummer herauszufinden.
Es wäre schon nett gewesen, das einmal zu demonstrieren. Ich habe mal ein wenig kombiniert und gemutmaßt, dass Du das so getestet hast:

Code: Alles auswählen

In [15]: data = "PokerStars Game #76620334109: Hold'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6:53:25 ET"

In [16]: strfromstr(data, "#", ":")
76620334109
flummi hat geschrieben: ich muss stri.pop (1) solange ausführen solange entweder kein fehler ausgespuckt wird, und falls fehler dann trotzdem mit dem code fortfahren, oder stri.pop (1) solange die liste 2 oder mehr elemente hat.

wie mach ich das jetzt am besten?
Ohne Dir zu nahe treten zu wollen: Am besten gar nicht erst einmal! Dein Code strotzt dermaßen von Anti-Pattern, dass man kaum weiß, wo man anfangen soll! Du solltest alles auf null zurück drehen und erst einmal ein Tutorial durch *arbeiten*. Dann versuche die grundlegenden Sprachelemente zu kapieren und selbständig anwenden zu können. Dieses Parsing ist noch eine Nummer zu hoch für Dich.

Damit Du aber etwas lernst, nehme ich das jetzt mal Schritt für Schritt auseinander... (`data` ist erste Zeile wie oben schon gezeigt)

Code: Alles auswählen

In [22]: res = data.split("#")

In [23]: res
Out[23]: 
['PokerStars Game ',
 "76620334109: Hold'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6:53:25 ET"]

In [24]: res.pop(0)
Out[24]: 'PokerStars Game '
In [22] trennen wir die Zeile am "#" auf und erhalten als Rückgabewert eine Liste mit Strings, wie man in [23] sieht. In [24] schmeißen wir das erste Element raus. So weit so einfach. Aber wozu machst Du das?

Code: Alles auswählen

In [25]: res
Out[25]: ["76620334109: Hold'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6:53:25 ET"]

In [26]: str(res)
Out[26]: '["76620334109: Hold\'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6:53:25 ET"]'
Aha. Du hast nun (mutmaßlich) nur noch ein Element in Deiner Liste. in [26] wandelst Du diese in einen String um. Das ist ziemlicher Murks! Zum einen kommen nun die syntaktischen Zeichen da mit rein `"[]`, zum anderen musst Du beim Format schon sehr genau wissen, dass es nur eine Raute in dieser Zeile gibt. Die Lösung ist also alles andere als robust.

Du willst ja in dem Resultat weiterarbeiten... wieso schnappst Du es Dir nicht direkt aus der Liste nach dem `split`? (Wenn Du bei `pop` einen Index mit dem *falschen* Teil angeben kannst, dann kannst Du doch auch gleich das Element hinter dem *gewünschten* Index rauspicken!?!)

Code: Alles auswählen

In [28]: data.split("#")[1]
Out[28]: "76620334109: Hold'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6:53:25 ET"
Das sieht doch viel einfacher und besser aus, oder?

Danach machst Du den gleichen Fehler noch einmal:

Code: Alles auswählen

In [29]: res = data.split("#")[1]

In [30]: res.split(":")
Out[30]: 
['76620334109',
 " Hold'em No Limit ($0.05/$0.10 USD) - 2012/03/04 6",
 '53',
 '25 ET']
Aha... hier kommen wohl mehrere Doppelpunkte vor. Also haust Du wieder die Liste so lange leer, bis nur noch ein Element vorhanden ist. Wozu das? Das *erste* Element muss doch das gewünschte sein!

Code: Alles auswählen

In [38]: res.split(":")[0]
Out[38]: '76620334109'
Das ist doch viel einfacher, als dann im letzten Schritt bei Dir, noch die syntaktischen Elemente per `strip` rauszuhauen, die man ja eigentlich nur durch die unsinnige Umwandlung der Liste in einen String bekommen hat. Zudem ist es Dir hier egal, wie viele Elemente in der Liste sind. Du willst ja nur das erste...

So und nun kommt's: Man kann das alles zusammenfassen!

Code: Alles auswählen

In [41]: data.split("#")[1].split(":")[0]
Out[41]: '76620334109'
Wow. Aus Deinem elf Zeiler ist ein Zweizeiler geworden...

Ach ja, sinnvoller als das `print` wäre es wohl, das Ergebnis zurückzugeben!

Generell ist diese Lösung aber eher mau. Mittels eines RegExps ließe sich die Nummer viel eleganter und robuster aus dem String holen:

Code: Alles auswählen

In [62]: res = re.search(r"#(?P<hand>\d+):", data)

In [63]: res.groupdict("hand")
Out[63]: {'hand': '76620334109'}
Sicherlich muss man sich in RegExps erst einmal einarbeiten, aber bei dem von Dir gezeigten Format meine ich, dass man damit sicherlich besser fährt, als mit reinen `split`-Operationen. Zumal diese keine reinen Key-Value-Paare liefern, sondern man zumindest im "Value"-Teil das ein oder andere noch zerlegen muss.

Ich denke Du musst auf jeden Fall erst einmal die Basics lernen. Ein simpler Indexzugriff auf SequenceTypes gehört sicherlich dazu ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@flummi: Nach eigener Aussage hast Du bereits „ein paar python bücher gelesen” und Du kennst nicht die absoluten Grundlagen; welche eingebauten Datentypen es gibt und welche grundlegenden Operationen darauf definiert sind‽
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Ärgerlich, dass anscheinend reines Lesen einem recht wenig beibringt :x
flummi
User
Beiträge: 33
Registriert: Samstag 28. April 2012, 13:33

danke erstmal das hat mein bild abgerundet. ich dachte auch dass das blöd ist alles andere immer rauszuhauen, statt das richtige zu picken, kannte aber die eckigen klammern nicht ;)


res.group () spuckt zwar einen string aus allerdings mit "#" und ":"

Code: Alles auswählen

'#76620334109:'
ich kann jetzt natürlich einfach

Code: Alles auswählen

res.group().strip ("#:")
oder gibts da wieder einen besseren weg?

ich will nämlich die ganzen zahlen später in eine liste spucken, um prüfen zu können ob die hand nicht schon ausgewertet worden ist... und ja das ist vllt ein großer sprung für mich, aber von nichts kommt nichts.

*edit* hat sich erledigt hab grad gelesen dass man auf diese sog. gruppen mit einem argument zugreifen kann. sprich

Code: Alles auswählen

res.group ("hand")
Zuletzt geändert von flummi am Freitag 11. Mai 2012, 17:58, insgesamt 1-mal geändert.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Du wirst sehr viele Probleme haben wenn du schon mehrere Bücher gelesen hast, aber in keinem davon weder Index-Zugriffe (Beispiel: a[0]) noch Slicing (Beispiel: a[2:3]) erwähnt wurden. Lerne also bitte die Grundlagen bevor du weiterhin versuchst irgendetwas funktionierendes zusammenzusfrickeln.
flummi
User
Beiträge: 33
Registriert: Samstag 28. April 2012, 13:33

doch stand drin, habs nur direkt wieder vergessen... http://openbook.galileocomputing.de/pyt ... 15_002.htm hab das hier bis kapitel 17 gelesen aber nur an zwei tagen... und python von kopf bis fuß an einem tag. da behält man sicherlich nicht viel, aber es reicht um nicht nur hyroglyphen zu sehen....

deswegen will ich jetzt rumspielen um auch was zu behalten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das OpenBook ist *schlecht*. Vergiss also, dass es das gibt und nutze eines der hier empfohlenen Dokumente.

Wenn die Zahl einer Hand einen Schlüssel darstellt, dann gibt es bessere Datenstrukturen als Listen, um diese sinnvoll zu verwalten / zu nutzen. Welche überlasse ich Dir mal als kleine Übungsaufgabe ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
flummi
User
Beiträge: 33
Registriert: Samstag 28. April 2012, 13:33

Code: Alles auswählen

data = "Seat 1: Schlienz ($14.98 in chips)"
res = re.search(r":\s(?P<spieler>\w+)\s(",data)


Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\Python27\lib\re.py", line 142, in search
    return _compile(pattern, flags).search(string)
  File "C:\Python27\lib\re.py", line 242, in _compile
    raise error, v # invalid expression
error: unbalanced parenthesis
ich wollte "Schlienz" durch
re.group ("spieler") kriegen...

da kommt ein leerzeichen nach ":" und vor "(" , deswegen hab ich jeweils einmal \s genommen. und "spieler" enthällt nur alphanumerische zeichen desweggen \w+

was läuft hier falsch?

*edit*

Code: Alles auswählen

res = re.search(r":\s(?P<spieler>\w+)\s\(",data)
hab nen backslash vergessen. weiß allerdings immer noch nicht wann man die setzen muss und wann nicht...
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Die Fehlermeldung sagt dir es doch schon. Die letzte Klammer wird als Anfang eines Gruppennamens interpretiert und da keine schließende folgt, beschwert sich der Regex-Compiler darüber. Du musst ihm also klarmachen, dass du dieses Zeichen wortwörtlich nutzen willst, was auch als Escaping bekannt ist. Dafür tut man einen Backslash vor das fragliche Zeichen.

Ich wiederhole mich an der Stelle, aber bitte arbeite zumindest das offizielle Tutorial durch (und damit meine ich nicht nur es durchzulesen, sondern tatsächlich alles an verwendetem Code zumindest im interaktivem Modus auszuprobieren oder noch besser kleine Skripte schreiben und diese ausführen), sonst wird das nichts wenn du schon an solchen Kleinigkeiten strauchelst.
BlackJack

@flummi: Du solltest bei einem Buch vielleicht nicht als Ziel haben es möglichst schnell durch zu haben, sondern möglichst viel zu verstehen. Ein ≈450-Seiten Buch wie „Python von Kopf bis Fuss” kann man nicht einfach so an einem Tag durchlesen. Man muss das durch*arbeiten* und nicht einfach nur lesen was da steht. Man muss den Code selber ausprobieren, verändern, eigenen schreiben und schauen ob das erwartete Ergebnis heraus kommt, um zu sehen ob man verstanden hat, was man gelesen hat. Programmieren lernt man nicht in dem man möglichst schnell viele Bücher durch liest.
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@flummi: Was - und ich wiederhole mich hierbei - BlackJack gesagt hat.

Außerdem ist es vielleicht wiedermal angezeigt, hierauf zu verlinken. Wenn man in solchen Zeiträumen denkt, dann ist es egal, ob man drei Tage oder drei Monate für ein Buch braucht. Wichtig ist, ist dass man es versteht. Wenn länger zum Lesen brauchen == besser verstehen, dann sollte man erst recht nicht ungeduldig sein. Vielleicht gilt das ja nur für mich, aber gute Computer-Bücher sind für mich auch Unterhaltungsliteratur.
In specifications, Murphy's Law supersedes Ohm's.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

pillmuncher hat geschrieben:Vielleicht gilt das ja nur für mich, aber gute Computer-Bücher sind für mich auch Unterhaltungsliteratur.
Das Problem ist, dass durch das Aufkommen von "für Dummies" und "in X Tagen" und Büchern die von Autoren geschrieben sind die keine Ahnung haben, es immer weniger solche Bücher gibt. "Programming Python" zumindest die dritte Edition eignet sich eher zum Schmunzeln, wo sie den Python-Browser vorgestellt haben, der vor 10 Jahren verstorben ist. "Hauptsache dick" scheint die Devise zu sein. Das ist mir auch beim Tanenbaum aufgefallen - das Buch ist an sich schon gut, aber wenn man das blabla streichen würde wäre das Buch nur noch 1/3 so lang und deutlich besser.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten