Frage zu Tutorial Programm

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
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Dienstag 7. November 2006, 01:00

Also ich habe folgendes Problem, ich komme mit einer Zeile eines Progammes aus einem Tutorial zum ermitteln der Wörter in einem Textdokument.
Programm:

Code: Alles auswählen

import string
def numworte(s):
    list = string.split(s) # erfordert die Qualifizierung split() mit dem Stringmodul
    return len(list) # gibt die Anzahl der Elemente in einer Liste zurück

inp = open("menue.txt","r")
total = 0  # initialisiert auf Null; erzeugt auch eine Variable

for line in inp.readlines():
    total = total + numworte(line) # akkumuliert Gesamtzahl für jede Zeile
print "Die Datei hat %d Worte" % total

inp.close()
Folgende Zeile macht mir Probleme:

Code: Alles auswählen

list = string.split(s)
Also, ich weiß das die Funktion die Anzahl an Wörtern in einer Zeile des Dokuments bestimmen soll..
Auch unklar ist mir wieso die variable line an s weitergegeben wird und bei split verwendet wird(wenn das stimmt^^).

Ps:Wenn es jmd hilft, die Anleitung ist auf http://www.freenetpages.co.uk/hp/alan.g ... tfiles.htm zu finden..
Gruss
merlin_emrys
User
Beiträge: 110
Registriert: Freitag 3. März 2006, 09:47

Dienstag 7. November 2006, 04:08

Sephiroth hat geschrieben: Folgende Zeile macht mir Probleme:

Code: Alles auswählen

list = string.split(s)
Also, ich weiß das die Funktion die Anzahl an Wörtern in einer Zeile des Dokuments bestimmen soll..
Auch unklar ist mir wieso die variable line an s weitergegeben wird und bei split verwendet wird(wenn das stimmt^^).
Wenn ich mir das richtig vorstelle, ist ziemlich egal, was in der Klammer hinter dem "numworte" steht, solange dasselbe hinter dem string.split wieder aufgegriffen wird. "numworte" ist so definiert, dass es etwas entgegennimmt, was es "splitten" kann, fuer sich selbst benennt es dies etwas dann halt auf Wunsch des Autors mit "s". Man haette es auch wieder "line" nennen koennen... Weitergegeben wird sie also einfach durch ihre Position in bezug auf die Klammern hinter "numworte" (wenn ich mir das richtig vorstelle :-o ).

Der "split"-Befehl zerlegt dann die Zeile in einzelne Teile (die pauschal als jeweils ein Wort betrachtet werden) und speichert jedes davon einzeln als Element der Liste "list". len(list) macht nichts als die Elemente dieser Liste (also die Worte dieser Zeile) zu zaehlen und das Ergebnis an das "Hauptprogramm" zu "melden".
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Dienstag 7. November 2006, 07:55

Hi Sephiroth,

ich möchte nur ergänzen, dass String-Objekte selbst die .split-Methode besitzen. Du könntest also auch schreiben:

Code: Alles auswählen

def numworte(sLine):
    lSplitList = sLine.split()
    return len(lSplitList)
Das hat den Vorteil, dass Du das Modul string hier nicht extra verwalten musst.
Ich habe versucht, eindeutige Namen zu verwenden. Der Beginn des Wortes gibt hier an, welchen Typ die Variable hat (s-String, l-Liste) und dahinter steht, was drin ist. Ich weiß, ich gehe da nicht ganz nach Python-Konvention. Aber für mich hat es sich als gut nachvollziehbar erwiesen.
Vorteil von split ist, dass es (ohne angegebene Argumente) den String an allen White-Spaces (Space, Tab, Enter) in Elemente von mindestens Länge eins teilt. Also

Code: Alles auswählen

"a      ,\n\nd".split()
ergibt trotzdem nur ['a', ',', 'd'] Wenn das Komma für Dich kein Wort ist, musst Du das extra behandeln.

Ich hoffe, das hat nicht mehr verwirrt als geholfen.

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dienstag 7. November 2006, 08:49

Das tolle ist ja, dass man alles in Pythons interaktiver Umgebung live ausprobieren kann:

Code: Alles auswählen

>>> s = "Hallo Welt, wie geht es dir?"
>>> wortliste = s.split() #Eine Liste mit allen Worten unseres Strings
>>> #Das gleiche wie: wortliste = string.split(s)
>>> print wortliste
['Hallo', 'Welt,', 'wie', 'geht', 'es', 'dir?']
>>> worte = len(wortliste) #Die Anzahl aller Worte unseres Strings
>>> print worte
6
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Dienstag 7. November 2006, 19:07

Das

Code: Alles auswählen

wortliste = s.split()
das gleiche wie

Code: Alles auswählen

wortliste = s.split(' ')
ist kann ich mir ja noch denken, aber wieso sit das das gleiche wie:

Code: Alles auswählen

wortliste = string.split(s)
Hier wird doch garnicht angezeigt wann der string gesplittet werden soll oder?
nur DAS er gesplittet werden soll, aber nicht das er bei jedem freespace geschnitten werden soll.
Wenn ich mir das richtig vorstelle, ist ziemlich egal, was in der Klammer hinter dem "numworte" steht, solange dasselbe hinter dem string.split wieder aufgegriffen wird. "numworte" ist so definiert, dass es etwas entgegennimmt, was es "splitten" kann, fuer sich selbst benennt es dies etwas dann halt auf Wunsch des Autors mit "s". Man haette es auch wieder "line" nennen koennen... Weitergegeben wird sie also einfach durch ihre Position in bezug auf die Klammern hinter "numworte" (wenn ich mir das richtig vorstelle ).
Also ist die s-variable die momentane Reihe in der die for-schleife steht, die also gesplittet werden soll und dann die wörter gezählt werden.
Also ein string..
es wird langsam klarer..=)


Nochne extra-Frage:Was bewirkt der return befehl in der Funktion?..

Gruss
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Dienstag 7. November 2006, 20:35

Hi Sephiroth,

Du scheinst es Dir schwieriger zu machen, als es ist. :-)
Sephiroth hat geschrieben:Das

Code: Alles auswählen

wortliste = s.split()
das gleiche wie

Code: Alles auswählen

wortliste = s.split(' ')
ist kann ich mir ja noch denken, ...
Das stimmt gerade nicht. Wenn Du einen Parameterstring übergibst (das darf nicht der Leerstring sein), dann wird der String s in Elemente gespalten, die durch den Parameterstring getrennt sind. Im zweiten Fall ist das ein Space-Zeichen, darum wird auch nur an Spaces getrennt - und zwar an jedem, auch wenn dabei in der resultierenden Liste ein Leerstring auftaucht.

Im ersten Fall wird kein Parameterstring übergeben, so dass vorgabemäßig an Whitespaces getrennt wird. Dazu gehören neben Space je nach Definition auch die Tabs (horizontal und vertikal), Zeilenvorschub und Zeilenumbruch. Zudem entstehen keine Leerstrings in der resultierenden Liste. Darum mein Beispiel oben mal interaktiv ausgeführt:

Code: Alles auswählen

>>> "a      ,\n\nd".split()
['a', ',', 'd']
>>> "a      ,\n\nd".split(' ')
['a', '', '', '', '', '', ',\n\nd']
Wie Du siehst ergeben sich ganz andere Resultate.
Sephiroth hat geschrieben:aber wieso sit das das gleiche wie:

Code: Alles auswählen

wortliste = string.split(s)
Hier wird doch garnicht angezeigt wann der string gesplittet werden soll oder?
nur DAS er gesplittet werden soll, aber nicht das er bei jedem freespace geschnitten werden soll.
s.split() und string.split(s) machen das gleiche, nur dass das Erste eine Methode eines Objekts vom Typ 'str' und das Zweite eine Funktion des Moduls string ist. In beiden Fällen wird bei fehlendem Übergabeparameter der Standardwert, Whitespaces, verwendet.

Im zweiten Fall können zwei Parameter übergeben werden, der erste ist der zu teilende String (s), der zweite der Trenn-String. Intern funktioniert das im ersten Fall auch so, nur dass bei Methoden das Objekt selbst meist automatisch übergeben wird.
Sephiroth hat geschrieben:Also ist die s-variable die momentane Reihe in der die for-schleife steht, die also gesplittet werden soll und dann die wörter gezählt werden.
Also ein string..
Richtig, es ist die im aktuellen Schleifendurchgang eingelesene Zeile. Wenn Du den Typ eines Objekts wissen möchtest, gib einfach folgendes ein:

Code: Alles auswählen

print type(Objekt)
Sephiroth hat geschrieben:Nochne extra-Frage:Was bewirkt der return befehl in der Funktion?
Der besagt, dass der Wert dahinter zurückgegeben werden soll. Wenn nichts angegeben wird, liefert es None zurück. Inhaltlich ist es egal, ob Du

Code: Alles auswählen

liste = 3
# oder
liste = len(line.split())
# oder
liste = numworte(line)
schreibst. Im normalen Leben ist ja auch 0.3 und 3/10 rein inhaltlich das gleiche. Der Rechenaufwand ist natürlich unterschiedlich.

Grüße,
der Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
BlackJack

Dienstag 7. November 2006, 20:52

Sephiroth hat geschrieben:Das

Code: Alles auswählen

wortliste = s.split()
das gleiche wie

Code: Alles auswählen

wortliste = s.split(' ')
ist kann ich mir ja noch denken,
Das stimmt nicht so ganz. Wenn Du ein Leerzeichen angibst, dann wird wirklich nur an Leerzeichen und auch an *jedem* Leerzeichen gesplittet. Ohne Argument wird an "whitespace" Zeichen, also Leerzeichen, Tabulatoren und Zeilenenden gesplittet *und* mehrere aufeinanderfolgende whitespaces werden vorher zu einem Zeichen zusammengefasst:

Code: Alles auswählen

In [1]: a = 'hello  world\nsecond\tline'

In [2]: print a
hello  world
second  line

In [3]: a.split()
Out[3]: ['hello', 'world', 'second', 'line']

In [4]: a.split(' ')
Out[4]: ['hello', '', 'world\nsecond\tline']

In [5]: a.split(None)
Out[5]: ['hello', 'world', 'second', 'line']
Wenn Du aus irgendeinem Grund "gezwungen" bist ein Argument zu übergeben und das Verhalten ohne Argument haben möchtest, dann kannst Du `None` übergeben.
aber wieso sit das das gleiche wie:

Code: Alles auswählen

wortliste = string.split(s)
Hier wird doch garnicht angezeigt wann der string gesplittet werden soll oder?
nur DAS er gesplittet werden soll, aber nicht das er bei jedem freespace geschnitten werden soll.
Das ist genau das gleiche wie bei `str.split()`, der optionale zweite Parameter ist `None`:

Code: Alles auswählen

In [7]: string.split(a)
Out[7]: ['hello', 'world', 'second', 'line']

In [8]: string.split(a, ' ')
Out[8]: ['hello', '', 'world\nsecond\tline']

In [9]: string.split(a, None)
Out[9]: ['hello', 'world', 'second', 'line']
Nochne extra-Frage:Was bewirkt der return befehl in der Funktion?
Der bewirkt, dass der folgende Ausdruck der Rückgabewert der Funktion ist. Das heisst Du kannst Dir vorstellen, dass der Aufruf der Funktion durch den Rückgabewert ersetzt wird. Genau wie bei Funktionen in der Mathematik.

Code: Alles auswählen

In [12]: def double(x):
   ....:     return 2 * x
   ....:

In [13]: a = double(10)

In [14]: print a
20

In [15]: print double(23) + double(double(42))
214
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Dienstag 7. November 2006, 22:49

Das stimmt gerade nicht. Wenn Du einen Parameterstring übergibst (das darf nicht der Leerstring sein), dann wird der String s in Elemente gespalten, die durch den Parameterstring getrennt sind. Im zweiten Fall ist das ein Space-Zeichen, darum wird auch nur an Spaces getrennt - und zwar an jedem, auch wenn dabei in der resultierenden Liste ein Leerstring auftaucht.

Im ersten Fall wird kein Parameterstring übergeben, so dass vorgabemäßig an Whitespaces getrennt wird. Dazu gehören neben Space je nach Definition auch die Tabs (horizontal und vertikal), Zeilenvorschub und Zeilenumbruch. Zudem entstehen keine Leerstrings in der resultierenden Liste. Darum mein Beispiel oben mal interaktiv ausgeführt:
OK=)..
s.split() und string.split(s) machen das gleiche, nur dass das Erste eine Methode eines Objekts vom Typ 'str' und das Zweite eine Funktion des Moduls string ist. In beiden Fällen wird bei fehlendem Übergabeparameter der Standardwert, Whitespaces, verwendet.

Im zweiten Fall können zwei Parameter übergeben werden, der erste ist der zu teilende String (s), der zweite der Trenn-String. Intern funktioniert das im ersten Fall auch so, nur dass bei Methoden das Objekt selbst meist automatisch übergeben wird.
Auch jetzt klar, aber wie gibt man im 2ten Fall den Trenn String an?
string.split(s,'k') oder so? im ersten ist es ja klar: s.split('k')

1 print type(Objekt)
Guter tipp..danke!
Der bewirkt, dass der folgende Ausdruck der Rückgabewert der Funktion ist. Das heisst Du kannst Dir vorstellen, dass der Aufruf der Funktion durch den Rückgabewert ersetzt wird. Genau wie bei Funktionen in der Mathematik.
Danke!!


Der rest ist klar..

..sehr gutes Forum hier, schnelle Hilfe;)

Gruss
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 7. November 2006, 23:07

Sephiroth hat geschrieben:Auch jetzt klar, aber wie gibt man im 2ten Fall den Trenn String an?
string.split(s,'k') oder so? im ersten ist es ja klar: s.split('k')
Wieso nicht selbst mal probieren?

Code: Alles auswählen

In [6]: string.split('kokosnuss', 'o')
Out[6]: ['k', 'k', 'snuss']
Ergo: du hast richtig vermutet.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Dienstag 7. November 2006, 23:17

Wieso nicht selbst mal probieren?
Bin bei meiner Freundin am PC;)
Ergo: du hast richtig vermutet.
Danke...somit ist alles geklärt und hier erstmal close..

Danke für die Hilfe an alle :wink:

Gruss
Antworten